3d-graphics 1.0
3d-project
json.hpp
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.5
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30/****************************************************************************\
31 * Note on documentation: The source files contain links to the online *
32 * documentation of the public API at https://json.nlohmann.me. This URL *
33 * contains the most recent documentation and should also be applicable to *
34 * previous versions; documentation for deprecated functions is not *
35 * removed, but marked deprecated. See "Generate documentation" section in *
36 * file docs/README.md. *
37\****************************************************************************/
38
39#ifndef INCLUDE_NLOHMANN_JSON_HPP_
40#define INCLUDE_NLOHMANN_JSON_HPP_
41
42#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
43#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
44#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 10 || NLOHMANN_JSON_VERSION_PATCH != 5
45#warning "Already included a different version of the library!"
46#endif
47#endif
48#endif
49
50#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
51#define NLOHMANN_JSON_VERSION_MINOR 10 // NOLINT(modernize-macro-to-enum)
52#define NLOHMANN_JSON_VERSION_PATCH 5 // NOLINT(modernize-macro-to-enum)
53
54#include <algorithm> // all_of, find, for_each
55#include <cstddef> // nullptr_t, ptrdiff_t, size_t
56#include <functional> // hash, less
57#include <initializer_list> // initializer_list
58#ifndef JSON_NO_IO
59#include <iosfwd> // istream, ostream
60#endif // JSON_NO_IO
61#include <iterator> // random_access_iterator_tag
62#include <memory> // unique_ptr
63#include <numeric> // accumulate
64#include <string> // string, stoi, to_string
65#include <utility> // declval, forward, move, pair, swap
66#include <vector> // vector
67
68// #include <nlohmann/adl_serializer.hpp>
69
70
71#include <type_traits>
72#include <utility>
73
74// #include <nlohmann/detail/conversions/from_json.hpp>
75
76
77#include <algorithm> // transform
78#include <array> // array
79#include <forward_list> // forward_list
80#include <iterator> // inserter, front_inserter, end
81#include <map> // map
82#include <string> // string
83#include <tuple> // tuple, make_tuple
84#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
85#include <unordered_map> // unordered_map
86#include <utility> // pair, declval
87#include <valarray> // valarray
88
89// #include <nlohmann/detail/exceptions.hpp>
90
91
92#include <cstddef> // nullptr_t
93#include <exception> // exception
94#include <stdexcept> // runtime_error
95#include <string> // to_string
96#include <vector> // vector
97
98// #include <nlohmann/detail/value_t.hpp>
99
100
101#include <array> // array
102#include <cstddef> // size_t
103#include <cstdint> // uint8_t
104#include <string> // string
105
106// #include <nlohmann/detail/macro_scope.hpp>
107
108
109#include <utility> // declval, pair
110// #include <nlohmann/thirdparty/hedley/hedley.hpp>
111
112
113/* Hedley - https://nemequ.github.io/hedley
114 * Created by Evan Nemerson <evan@nemerson.com>
115 *
116 * To the extent possible under law, the author(s) have dedicated all
117 * copyright and related and neighboring rights to this software to
118 * the public domain worldwide. This software is distributed without
119 * any warranty.
120 *
121 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
122 * SPDX-License-Identifier: CC0-1.0
123 */
124
125#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
126#if defined(JSON_HEDLEY_VERSION)
127#undef JSON_HEDLEY_VERSION
128#endif
129#define JSON_HEDLEY_VERSION 15
130
131#if defined(JSON_HEDLEY_STRINGIFY_EX)
132#undef JSON_HEDLEY_STRINGIFY_EX
133#endif
134#define JSON_HEDLEY_STRINGIFY_EX(x) #x
135
136#if defined(JSON_HEDLEY_STRINGIFY)
137#undef JSON_HEDLEY_STRINGIFY
138#endif
139#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
140
141#if defined(JSON_HEDLEY_CONCAT_EX)
142#undef JSON_HEDLEY_CONCAT_EX
143#endif
144#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
145
146#if defined(JSON_HEDLEY_CONCAT)
147#undef JSON_HEDLEY_CONCAT
148#endif
149#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
150
151#if defined(JSON_HEDLEY_CONCAT3_EX)
152#undef JSON_HEDLEY_CONCAT3_EX
153#endif
154#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
155
156#if defined(JSON_HEDLEY_CONCAT3)
157#undef JSON_HEDLEY_CONCAT3
158#endif
159#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
160
161#if defined(JSON_HEDLEY_VERSION_ENCODE)
162#undef JSON_HEDLEY_VERSION_ENCODE
163#endif
164#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
165
166#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
167#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
168#endif
169#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
170
171#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
172#undef JSON_HEDLEY_VERSION_DECODE_MINOR
173#endif
174#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
175
176#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
177#undef JSON_HEDLEY_VERSION_DECODE_REVISION
178#endif
179#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
180
181#if defined(JSON_HEDLEY_GNUC_VERSION)
182#undef JSON_HEDLEY_GNUC_VERSION
183#endif
184#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
185#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
186#elif defined(__GNUC__)
187#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
188#endif
189
190#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
191#undef JSON_HEDLEY_GNUC_VERSION_CHECK
192#endif
193#if defined(JSON_HEDLEY_GNUC_VERSION)
194#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
195#else
196#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
197#endif
198
199#if defined(JSON_HEDLEY_MSVC_VERSION)
200#undef JSON_HEDLEY_MSVC_VERSION
201#endif
202#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
203#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
204#elif defined(_MSC_FULL_VER) && !defined(__ICL)
205#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
206#elif defined(_MSC_VER) && !defined(__ICL)
207#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
208#endif
209
210#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
211#undef JSON_HEDLEY_MSVC_VERSION_CHECK
212#endif
213#if !defined(JSON_HEDLEY_MSVC_VERSION)
214#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
215#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
216#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
217#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
218#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
219#else
220#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
221#endif
222
223#if defined(JSON_HEDLEY_INTEL_VERSION)
224#undef JSON_HEDLEY_INTEL_VERSION
225#endif
226#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
227#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
228#elif defined(__INTEL_COMPILER) && !defined(__ICL)
229#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
230#endif
231
232#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
233#undef JSON_HEDLEY_INTEL_VERSION_CHECK
234#endif
235#if defined(JSON_HEDLEY_INTEL_VERSION)
236#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
237#else
238#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
239#endif
240
241#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
242#undef JSON_HEDLEY_INTEL_CL_VERSION
243#endif
244#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
245#define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
246#endif
247
248#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
249#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
250#endif
251#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
252#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
253#else
254#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
255#endif
256
257#if defined(JSON_HEDLEY_PGI_VERSION)
258#undef JSON_HEDLEY_PGI_VERSION
259#endif
260#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
261#define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
262#endif
263
264#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
265#undef JSON_HEDLEY_PGI_VERSION_CHECK
266#endif
267#if defined(JSON_HEDLEY_PGI_VERSION)
268#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
269#else
270#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
271#endif
272
273#if defined(JSON_HEDLEY_SUNPRO_VERSION)
274#undef JSON_HEDLEY_SUNPRO_VERSION
275#endif
276#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
277#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
278#elif defined(__SUNPRO_C)
279#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
280#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
281#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
282#elif defined(__SUNPRO_CC)
283#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
284#endif
285
286#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
287#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
288#endif
289#if defined(JSON_HEDLEY_SUNPRO_VERSION)
290#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
291#else
292#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
293#endif
294
295#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
296#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
297#endif
298#if defined(__EMSCRIPTEN__)
299#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
300#endif
301
302#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
303#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
304#endif
305#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
306#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
307#else
308#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
309#endif
310
311#if defined(JSON_HEDLEY_ARM_VERSION)
312#undef JSON_HEDLEY_ARM_VERSION
313#endif
314#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
315#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
316#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
317#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
318#endif
319
320#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
321#undef JSON_HEDLEY_ARM_VERSION_CHECK
322#endif
323#if defined(JSON_HEDLEY_ARM_VERSION)
324#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
325#else
326#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
327#endif
328
329#if defined(JSON_HEDLEY_IBM_VERSION)
330#undef JSON_HEDLEY_IBM_VERSION
331#endif
332#if defined(__ibmxl__)
333#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
334#elif defined(__xlC__) && defined(__xlC_ver__)
335#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
336#elif defined(__xlC__)
337#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
338#endif
339
340#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
341#undef JSON_HEDLEY_IBM_VERSION_CHECK
342#endif
343#if defined(JSON_HEDLEY_IBM_VERSION)
344#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
345#else
346#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
347#endif
348
349#if defined(JSON_HEDLEY_TI_VERSION)
350#undef JSON_HEDLEY_TI_VERSION
351#endif
352#if \
353 defined(__TI_COMPILER_VERSION__) && \
354 ( \
355 defined(__TMS470__) || defined(__TI_ARM__) || \
356 defined(__MSP430__) || \
357 defined(__TMS320C2000__) \
358 )
359#if (__TI_COMPILER_VERSION__ >= 16000000)
360#define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
361#endif
362#endif
363
364#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
365#undef JSON_HEDLEY_TI_VERSION_CHECK
366#endif
367#if defined(JSON_HEDLEY_TI_VERSION)
368#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
369#else
370#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
371#endif
372
373#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
374#undef JSON_HEDLEY_TI_CL2000_VERSION
375#endif
376#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
377#define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
378#endif
379
380#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
381#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
382#endif
383#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
384#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
385#else
386#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
387#endif
388
389#if defined(JSON_HEDLEY_TI_CL430_VERSION)
390#undef JSON_HEDLEY_TI_CL430_VERSION
391#endif
392#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
393#define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
394#endif
395
396#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
397#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
398#endif
399#if defined(JSON_HEDLEY_TI_CL430_VERSION)
400#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
401#else
402#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
403#endif
404
405#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
406#undef JSON_HEDLEY_TI_ARMCL_VERSION
407#endif
408#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
409#define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
410#endif
411
412#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
413#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
414#endif
415#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
416#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
417#else
418#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
419#endif
420
421#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
422#undef JSON_HEDLEY_TI_CL6X_VERSION
423#endif
424#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
425#define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
426#endif
427
428#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
429#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
430#endif
431#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
432#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
433#else
434#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
435#endif
436
437#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
438#undef JSON_HEDLEY_TI_CL7X_VERSION
439#endif
440#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
441#define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
442#endif
443
444#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
445#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
446#endif
447#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
448#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
449#else
450#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
451#endif
452
453#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
454#undef JSON_HEDLEY_TI_CLPRU_VERSION
455#endif
456#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
457#define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
458#endif
459
460#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
461#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
462#endif
463#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
464#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
465#else
466#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
467#endif
468
469#if defined(JSON_HEDLEY_CRAY_VERSION)
470#undef JSON_HEDLEY_CRAY_VERSION
471#endif
472#if defined(_CRAYC)
473#if defined(_RELEASE_PATCHLEVEL)
474#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
475#else
476#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
477#endif
478#endif
479
480#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
481#undef JSON_HEDLEY_CRAY_VERSION_CHECK
482#endif
483#if defined(JSON_HEDLEY_CRAY_VERSION)
484#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
485#else
486#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
487#endif
488
489#if defined(JSON_HEDLEY_IAR_VERSION)
490#undef JSON_HEDLEY_IAR_VERSION
491#endif
492#if defined(__IAR_SYSTEMS_ICC__)
493#if __VER__ > 1000
494#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
495#else
496#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
497#endif
498#endif
499
500#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
501#undef JSON_HEDLEY_IAR_VERSION_CHECK
502#endif
503#if defined(JSON_HEDLEY_IAR_VERSION)
504#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
505#else
506#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
507#endif
508
509#if defined(JSON_HEDLEY_TINYC_VERSION)
510#undef JSON_HEDLEY_TINYC_VERSION
511#endif
512#if defined(__TINYC__)
513#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
514#endif
515
516#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
517#undef JSON_HEDLEY_TINYC_VERSION_CHECK
518#endif
519#if defined(JSON_HEDLEY_TINYC_VERSION)
520#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
521#else
522#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
523#endif
524
525#if defined(JSON_HEDLEY_DMC_VERSION)
526#undef JSON_HEDLEY_DMC_VERSION
527#endif
528#if defined(__DMC__)
529#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
530#endif
531
532#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
533#undef JSON_HEDLEY_DMC_VERSION_CHECK
534#endif
535#if defined(JSON_HEDLEY_DMC_VERSION)
536#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
537#else
538#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
539#endif
540
541#if defined(JSON_HEDLEY_COMPCERT_VERSION)
542#undef JSON_HEDLEY_COMPCERT_VERSION
543#endif
544#if defined(__COMPCERT_VERSION__)
545#define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
546#endif
547
548#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
549#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
550#endif
551#if defined(JSON_HEDLEY_COMPCERT_VERSION)
552#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
553#else
554#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
555#endif
556
557#if defined(JSON_HEDLEY_PELLES_VERSION)
558#undef JSON_HEDLEY_PELLES_VERSION
559#endif
560#if defined(__POCC__)
561#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
562#endif
563
564#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
565#undef JSON_HEDLEY_PELLES_VERSION_CHECK
566#endif
567#if defined(JSON_HEDLEY_PELLES_VERSION)
568#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
569#else
570#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
571#endif
572
573#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
574#undef JSON_HEDLEY_MCST_LCC_VERSION
575#endif
576#if defined(__LCC__) && defined(__LCC_MINOR__)
577#define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
578#endif
579
580#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
581#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
582#endif
583#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
584#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
585#else
586#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
587#endif
588
589#if defined(JSON_HEDLEY_GCC_VERSION)
590#undef JSON_HEDLEY_GCC_VERSION
591#endif
592#if \
593 defined(JSON_HEDLEY_GNUC_VERSION) && \
594 !defined(__clang__) && \
595 !defined(JSON_HEDLEY_INTEL_VERSION) && \
596 !defined(JSON_HEDLEY_PGI_VERSION) && \
597 !defined(JSON_HEDLEY_ARM_VERSION) && \
598 !defined(JSON_HEDLEY_CRAY_VERSION) && \
599 !defined(JSON_HEDLEY_TI_VERSION) && \
600 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
601 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
602 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
603 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
604 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
605 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
606 !defined(__COMPCERT__) && \
607 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
608#define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
609#endif
610
611#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
612#undef JSON_HEDLEY_GCC_VERSION_CHECK
613#endif
614#if defined(JSON_HEDLEY_GCC_VERSION)
615#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
616#else
617#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
618#endif
619
620#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
621#undef JSON_HEDLEY_HAS_ATTRIBUTE
622#endif
623#if \
624 defined(__has_attribute) && \
625 ( \
626 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
627 )
628# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
629#else
630# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
631#endif
632
633#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
634#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
635#endif
636#if defined(__has_attribute)
637#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
638#else
639#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
640#endif
641
642#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
643#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
644#endif
645#if defined(__has_attribute)
646#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
647#else
648#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
649#endif
650
651#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
652#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
653#endif
654#if \
655 defined(__has_cpp_attribute) && \
656 defined(__cplusplus) && \
657 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
658#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
659#else
660#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
661#endif
662
663#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
664#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
665#endif
666#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
667#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
668#elif \
669 !defined(JSON_HEDLEY_PGI_VERSION) && \
670 !defined(JSON_HEDLEY_IAR_VERSION) && \
671 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
672 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
673#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
674#else
675#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
676#endif
677
678#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
679#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
680#endif
681#if defined(__has_cpp_attribute) && defined(__cplusplus)
682#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
683#else
684#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
685#endif
686
687#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
688#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
689#endif
690#if defined(__has_cpp_attribute) && defined(__cplusplus)
691#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
692#else
693#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
694#endif
695
696#if defined(JSON_HEDLEY_HAS_BUILTIN)
697#undef JSON_HEDLEY_HAS_BUILTIN
698#endif
699#if defined(__has_builtin)
700#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
701#else
702#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
703#endif
704
705#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
706#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
707#endif
708#if defined(__has_builtin)
709#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
710#else
711#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
712#endif
713
714#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
715#undef JSON_HEDLEY_GCC_HAS_BUILTIN
716#endif
717#if defined(__has_builtin)
718#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
719#else
720#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
721#endif
722
723#if defined(JSON_HEDLEY_HAS_FEATURE)
724#undef JSON_HEDLEY_HAS_FEATURE
725#endif
726#if defined(__has_feature)
727#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
728#else
729#define JSON_HEDLEY_HAS_FEATURE(feature) (0)
730#endif
731
732#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
733#undef JSON_HEDLEY_GNUC_HAS_FEATURE
734#endif
735#if defined(__has_feature)
736#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
737#else
738#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
739#endif
740
741#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
742#undef JSON_HEDLEY_GCC_HAS_FEATURE
743#endif
744#if defined(__has_feature)
745#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
746#else
747#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
748#endif
749
750#if defined(JSON_HEDLEY_HAS_EXTENSION)
751#undef JSON_HEDLEY_HAS_EXTENSION
752#endif
753#if defined(__has_extension)
754#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
755#else
756#define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
757#endif
758
759#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
760#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
761#endif
762#if defined(__has_extension)
763#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
764#else
765#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
766#endif
767
768#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
769#undef JSON_HEDLEY_GCC_HAS_EXTENSION
770#endif
771#if defined(__has_extension)
772#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
773#else
774#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
775#endif
776
777#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
778#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
779#endif
780#if defined(__has_declspec_attribute)
781#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
782#else
783#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
784#endif
785
786#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
787#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
788#endif
789#if defined(__has_declspec_attribute)
790#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
791#else
792#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
793#endif
794
795#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
796#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
797#endif
798#if defined(__has_declspec_attribute)
799#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
800#else
801#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
802#endif
803
804#if defined(JSON_HEDLEY_HAS_WARNING)
805#undef JSON_HEDLEY_HAS_WARNING
806#endif
807#if defined(__has_warning)
808#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
809#else
810#define JSON_HEDLEY_HAS_WARNING(warning) (0)
811#endif
812
813#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
814#undef JSON_HEDLEY_GNUC_HAS_WARNING
815#endif
816#if defined(__has_warning)
817#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
818#else
819#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
820#endif
821
822#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
823#undef JSON_HEDLEY_GCC_HAS_WARNING
824#endif
825#if defined(__has_warning)
826#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
827#else
828#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
829#endif
830
831#if \
832 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
833 defined(__clang__) || \
834 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
835 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
836 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
837 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
838 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
839 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
840 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
841 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
842 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
843 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
844 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
845 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
846 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
847 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
848 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
849 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
850#define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
851#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
852#define JSON_HEDLEY_PRAGMA(value) __pragma(value)
853#else
854#define JSON_HEDLEY_PRAGMA(value)
855#endif
856
857#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
858#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
859#endif
860#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
861#undef JSON_HEDLEY_DIAGNOSTIC_POP
862#endif
863#if defined(__clang__)
864#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
865#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
866#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
867#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
868#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
869#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
870#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
871#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
872#elif \
873 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
874 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
875#define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
876#define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
877#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
878#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
879#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
880#elif \
881 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
882 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
883 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
884 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
885 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
886 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
887#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
888#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
889#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
890#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
891#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
892#else
893#define JSON_HEDLEY_DIAGNOSTIC_PUSH
894#define JSON_HEDLEY_DIAGNOSTIC_POP
895#endif
896
897 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
898 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
899#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
900#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
901#endif
902#if defined(__cplusplus)
903# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
904# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
905# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
906# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
907 JSON_HEDLEY_DIAGNOSTIC_PUSH \
908 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
909 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
910 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
911 xpr \
912 JSON_HEDLEY_DIAGNOSTIC_POP
913# else
914# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
915 JSON_HEDLEY_DIAGNOSTIC_PUSH \
916 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
917 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
918 xpr \
919 JSON_HEDLEY_DIAGNOSTIC_POP
920# endif
921# else
922# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
923 JSON_HEDLEY_DIAGNOSTIC_PUSH \
924 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
925 xpr \
926 JSON_HEDLEY_DIAGNOSTIC_POP
927# endif
928# endif
929#endif
930#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
931#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
932#endif
933
934#if defined(JSON_HEDLEY_CONST_CAST)
935#undef JSON_HEDLEY_CONST_CAST
936#endif
937#if defined(__cplusplus)
938# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
939#elif \
940 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
941 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
942 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
943# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
944 JSON_HEDLEY_DIAGNOSTIC_PUSH \
945 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
946 ((T) (expr)); \
947 JSON_HEDLEY_DIAGNOSTIC_POP \
948 }))
949#else
950# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
951#endif
952
953#if defined(JSON_HEDLEY_REINTERPRET_CAST)
954#undef JSON_HEDLEY_REINTERPRET_CAST
955#endif
956#if defined(__cplusplus)
957#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
958#else
959#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
960#endif
961
962#if defined(JSON_HEDLEY_STATIC_CAST)
963#undef JSON_HEDLEY_STATIC_CAST
964#endif
965#if defined(__cplusplus)
966#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
967#else
968#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
969#endif
970
971#if defined(JSON_HEDLEY_CPP_CAST)
972#undef JSON_HEDLEY_CPP_CAST
973#endif
974#if defined(__cplusplus)
975# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
976# define JSON_HEDLEY_CPP_CAST(T, expr) \
977 JSON_HEDLEY_DIAGNOSTIC_PUSH \
978 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
979 ((T) (expr)) \
980 JSON_HEDLEY_DIAGNOSTIC_POP
981# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
982# define JSON_HEDLEY_CPP_CAST(T, expr) \
983 JSON_HEDLEY_DIAGNOSTIC_PUSH \
984 _Pragma("diag_suppress=Pe137") \
985 JSON_HEDLEY_DIAGNOSTIC_POP
986# else
987# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
988# endif
989#else
990# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
991#endif
992
993#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
994#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
995#endif
996#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
997#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
998#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
999#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1000#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1001#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1002#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1003#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1004#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1005#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1006#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1007#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1008#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1009#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1010#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1011#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1012#elif \
1013 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1014 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1015 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1016 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1017 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1018 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1019 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1020 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1021 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1022 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1023 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1024#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1025#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1026#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1027#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1028#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1029#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1030#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1031#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1032#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1033#else
1034#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1035#endif
1036
1037#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1038#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1039#endif
1040#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1041#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1042#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1043#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1044#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1045#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1046#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1047#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1048#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1049#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1050#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1051#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1052#elif \
1053 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1054 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1055 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1056 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1057#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1058#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1059#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1060#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1061#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1062#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1063#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1064#else
1065#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1066#endif
1067
1068#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1069#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1070#endif
1071#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1072#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1073#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1074#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1075#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1076#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1077#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1078#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1079#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1080#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1081#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1082#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1083#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1084#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1085#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1086#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1087#elif \
1088 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1089 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1090 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1091#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1092#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1093#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1094#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1095#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1096#else
1097#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1098#endif
1099
1100#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1101#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1102#endif
1103#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1104#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1105#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1106#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1107#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1108#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1109#else
1110#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1111#endif
1112
1113#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1114#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1115#endif
1116#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1117#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1118#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1119#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1120#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1121#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1122#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1123#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1124#else
1125#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1126#endif
1127
1128#if defined(JSON_HEDLEY_DEPRECATED)
1129#undef JSON_HEDLEY_DEPRECATED
1130#endif
1131#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1132#undef JSON_HEDLEY_DEPRECATED_FOR
1133#endif
1134#if \
1135 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1136 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1137#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1138#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1139#elif \
1140 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1141 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1142 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1143 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1144 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1145 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1146 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1147 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1148 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1149 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1150 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1151 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1152#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1153#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1154#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1155#define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1156#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1157#elif \
1158 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1159 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1160 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1161 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1162 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1163 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1164 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1165 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1166 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1167 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1168 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1169 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1170 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1171 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1172 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1173 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1174#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1175#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1176#elif \
1177 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1178 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1179 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1180#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1181#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1182#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1183#define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1184#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1185#else
1186#define JSON_HEDLEY_DEPRECATED(since)
1187#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1188#endif
1189
1190#if defined(JSON_HEDLEY_UNAVAILABLE)
1191#undef JSON_HEDLEY_UNAVAILABLE
1192#endif
1193#if \
1194 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1195 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1196 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1197 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1198#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1199#else
1200#define JSON_HEDLEY_UNAVAILABLE(available_since)
1201#endif
1202
1203#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1204#undef JSON_HEDLEY_WARN_UNUSED_RESULT
1205#endif
1206#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1207#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1208#endif
1209#if \
1210 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1211 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1212 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1213 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1214 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1215 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1216 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1217 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1218 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1219 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1220 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1221 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1222 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1223 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1224 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1225 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1226 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1227#define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1228#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1229#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1230#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1231#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1232#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1233#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1234#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1235#elif defined(_Check_return_) /* SAL */
1236#define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1237#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1238#else
1239#define JSON_HEDLEY_WARN_UNUSED_RESULT
1240#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1241#endif
1242
1243#if defined(JSON_HEDLEY_SENTINEL)
1244#undef JSON_HEDLEY_SENTINEL
1245#endif
1246#if \
1247 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1248 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1249 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1250 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1251 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1252#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1253#else
1254#define JSON_HEDLEY_SENTINEL(position)
1255#endif
1256
1257#if defined(JSON_HEDLEY_NO_RETURN)
1258#undef JSON_HEDLEY_NO_RETURN
1259#endif
1260#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1261#define JSON_HEDLEY_NO_RETURN __noreturn
1262#elif \
1263 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1264 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1265#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1266#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1267#define JSON_HEDLEY_NO_RETURN _Noreturn
1268#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1269#define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1270#elif \
1271 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1272 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1273 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1274 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1275 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1276 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1277 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1279 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1281 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1283 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1284 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1285 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1286 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1287 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1288#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1289#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1290#define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1291#elif \
1292 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1293 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1294#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1295#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1296#define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1297#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1298#define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1299#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1300#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1301#else
1302#define JSON_HEDLEY_NO_RETURN
1303#endif
1304
1305#if defined(JSON_HEDLEY_NO_ESCAPE)
1306#undef JSON_HEDLEY_NO_ESCAPE
1307#endif
1308#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1309#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1310#else
1311#define JSON_HEDLEY_NO_ESCAPE
1312#endif
1313
1314#if defined(JSON_HEDLEY_UNREACHABLE)
1315#undef JSON_HEDLEY_UNREACHABLE
1316#endif
1317#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1318#undef JSON_HEDLEY_UNREACHABLE_RETURN
1319#endif
1320#if defined(JSON_HEDLEY_ASSUME)
1321#undef JSON_HEDLEY_ASSUME
1322#endif
1323#if \
1324 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1325 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1326 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1327#define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1328#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1329#define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1330#elif \
1331 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1332 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1333#if defined(__cplusplus)
1334#define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1335#else
1336#define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1337#endif
1338#endif
1339#if \
1340 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1341 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1342 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1343 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1344 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1345 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1346 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1347#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1348#elif defined(JSON_HEDLEY_ASSUME)
1349#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1350#endif
1351#if !defined(JSON_HEDLEY_ASSUME)
1352#if defined(JSON_HEDLEY_UNREACHABLE)
1353#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1354#else
1355#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1356#endif
1357#endif
1358#if defined(JSON_HEDLEY_UNREACHABLE)
1359#if \
1360 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1361 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1362#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1363#else
1364#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1365#endif
1366#else
1367#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1368#endif
1369#if !defined(JSON_HEDLEY_UNREACHABLE)
1370#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1371#endif
1372
1374#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1375#pragma clang diagnostic ignored "-Wpedantic"
1376#endif
1377#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1378#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1379#endif
1380#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1381#if defined(__clang__)
1382#pragma clang diagnostic ignored "-Wvariadic-macros"
1383#elif defined(JSON_HEDLEY_GCC_VERSION)
1384#pragma GCC diagnostic ignored "-Wvariadic-macros"
1385#endif
1386#endif
1387#if defined(JSON_HEDLEY_NON_NULL)
1388#undef JSON_HEDLEY_NON_NULL
1389#endif
1390#if \
1391 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1392 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1393 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1394 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1395#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1396#else
1397#define JSON_HEDLEY_NON_NULL(...)
1398#endif
1400
1401#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1402#undef JSON_HEDLEY_PRINTF_FORMAT
1403#endif
1404#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1405#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1406#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1407#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1408#elif \
1409 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1410 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1411 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1412 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1413 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1414 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1415 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1416 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1417 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1418 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1419 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1420 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1421 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1422 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1423 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1424 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1425 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1426#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1427#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1428#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1429#else
1430#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1431#endif
1432
1433#if defined(JSON_HEDLEY_CONSTEXPR)
1434#undef JSON_HEDLEY_CONSTEXPR
1435#endif
1436#if defined(__cplusplus)
1437#if __cplusplus >= 201103L
1438#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1439#endif
1440#endif
1441#if !defined(JSON_HEDLEY_CONSTEXPR)
1442#define JSON_HEDLEY_CONSTEXPR
1443#endif
1444
1445#if defined(JSON_HEDLEY_PREDICT)
1446#undef JSON_HEDLEY_PREDICT
1447#endif
1448#if defined(JSON_HEDLEY_LIKELY)
1449#undef JSON_HEDLEY_LIKELY
1450#endif
1451#if defined(JSON_HEDLEY_UNLIKELY)
1452#undef JSON_HEDLEY_UNLIKELY
1453#endif
1454#if defined(JSON_HEDLEY_UNPREDICTABLE)
1455#undef JSON_HEDLEY_UNPREDICTABLE
1456#endif
1457#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1458#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1459#endif
1460#if \
1461 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1462 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1463 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1464# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1465# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1466# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1467# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1468# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1469#elif \
1470 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1471 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1472 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1474 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1475 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1476 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1477 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1478 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1479 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1480 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1481 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1482 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1483 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1484 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1485 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1486# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1487 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1488# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1489 (__extension__ ({ \
1490 double hedley_probability_ = (probability); \
1491 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1492 }))
1493# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1494 (__extension__ ({ \
1495 double hedley_probability_ = (probability); \
1496 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1497 }))
1498# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1499# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1500#else
1501# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1502# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1503# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1504# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1505# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1506#endif
1507#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1508#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1509#endif
1510
1511#if defined(JSON_HEDLEY_MALLOC)
1512#undef JSON_HEDLEY_MALLOC
1513#endif
1514#if \
1515 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1516 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1517 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1518 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1519 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1520 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1521 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1522 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1523 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1524 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1525 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1526 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1527 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1528 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1529 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1530 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1531 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1532 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1533#define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1534#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1535#define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1536#elif \
1537 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1538 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1539#define JSON_HEDLEY_MALLOC __declspec(restrict)
1540#else
1541#define JSON_HEDLEY_MALLOC
1542#endif
1543
1544#if defined(JSON_HEDLEY_PURE)
1545#undef JSON_HEDLEY_PURE
1546#endif
1547#if \
1548 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1549 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1550 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1551 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1552 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1553 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1554 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1555 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1556 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1557 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1558 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1559 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1560 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1561 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1562 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1563 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1564 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1565 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1566 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1567# define JSON_HEDLEY_PURE __attribute__((__pure__))
1568#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1569# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1570#elif defined(__cplusplus) && \
1571 ( \
1572 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1573 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1574 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1575 )
1576# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1577#else
1578# define JSON_HEDLEY_PURE
1579#endif
1580
1581#if defined(JSON_HEDLEY_CONST)
1582#undef JSON_HEDLEY_CONST
1583#endif
1584#if \
1585 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1586 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1587 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1588 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1589 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1590 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1591 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1592 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1593 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1594 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1595 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1596 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1597 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1598 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1599 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1600 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1601 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1602 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1603 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1604#define JSON_HEDLEY_CONST __attribute__((__const__))
1605#elif \
1606 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1607#define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1608#else
1609#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1610#endif
1611
1612#if defined(JSON_HEDLEY_RESTRICT)
1613#undef JSON_HEDLEY_RESTRICT
1614#endif
1615#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1616#define JSON_HEDLEY_RESTRICT restrict
1617#elif \
1618 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1619 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1620 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1621 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1622 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1623 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1624 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1625 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1626 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1627 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1628 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1629 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1630 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1631 defined(__clang__) || \
1632 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1633#define JSON_HEDLEY_RESTRICT __restrict
1634#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1635#define JSON_HEDLEY_RESTRICT _Restrict
1636#else
1637#define JSON_HEDLEY_RESTRICT
1638#endif
1639
1640#if defined(JSON_HEDLEY_INLINE)
1641#undef JSON_HEDLEY_INLINE
1642#endif
1643#if \
1644 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1645 (defined(__cplusplus) && (__cplusplus >= 199711L))
1646#define JSON_HEDLEY_INLINE inline
1647#elif \
1648 defined(JSON_HEDLEY_GCC_VERSION) || \
1649 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1650#define JSON_HEDLEY_INLINE __inline__
1651#elif \
1652 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1653 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1654 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1655 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1656 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1657 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1658 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1659 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1660 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1661 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1662#define JSON_HEDLEY_INLINE __inline
1663#else
1664#define JSON_HEDLEY_INLINE
1665#endif
1666
1667#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1668#undef JSON_HEDLEY_ALWAYS_INLINE
1669#endif
1670#if \
1671 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1672 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1673 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1674 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1675 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1676 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1677 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1678 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1679 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1680 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1681 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1682 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1683 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1684 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1685 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1686 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1687 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1688 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1689 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1690# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1691#elif \
1692 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1693 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1694# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1695#elif defined(__cplusplus) && \
1696 ( \
1697 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1698 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1699 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1700 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1701 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1702 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1703 )
1704# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1705#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1706# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1707#else
1708# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1709#endif
1710
1711#if defined(JSON_HEDLEY_NEVER_INLINE)
1712#undef JSON_HEDLEY_NEVER_INLINE
1713#endif
1714#if \
1715 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1716 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1717 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1718 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1719 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1720 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1721 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1722 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1723 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1724 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1725 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1726 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1727 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1728 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1729 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1730 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1731 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1732 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1733 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1734#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1735#elif \
1736 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1737 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1738#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1739#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1740#define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1741#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1742#define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1743#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1744#define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1745#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1746#define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1747#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1748#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1749#else
1750#define JSON_HEDLEY_NEVER_INLINE
1751#endif
1752
1753#if defined(JSON_HEDLEY_PRIVATE)
1754#undef JSON_HEDLEY_PRIVATE
1755#endif
1756#if defined(JSON_HEDLEY_PUBLIC)
1757#undef JSON_HEDLEY_PUBLIC
1758#endif
1759#if defined(JSON_HEDLEY_IMPORT)
1760#undef JSON_HEDLEY_IMPORT
1761#endif
1762#if defined(_WIN32) || defined(__CYGWIN__)
1763# define JSON_HEDLEY_PRIVATE
1764# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1765# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1766#else
1767# if \
1768 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1769 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1770 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1771 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1772 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1773 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1774 ( \
1775 defined(__TI_EABI__) && \
1776 ( \
1777 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1778 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1779 ) \
1780 ) || \
1781 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1782# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1783# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1784# else
1785# define JSON_HEDLEY_PRIVATE
1786# define JSON_HEDLEY_PUBLIC
1787# endif
1788# define JSON_HEDLEY_IMPORT extern
1789#endif
1790
1791#if defined(JSON_HEDLEY_NO_THROW)
1792#undef JSON_HEDLEY_NO_THROW
1793#endif
1794#if \
1795 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1796 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1797 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1798 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1799#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1800#elif \
1801 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1802 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1803 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1804#define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1805#else
1806#define JSON_HEDLEY_NO_THROW
1807#endif
1808
1809#if defined(JSON_HEDLEY_FALL_THROUGH)
1810#undef JSON_HEDLEY_FALL_THROUGH
1811#endif
1812#if \
1813 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1814 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1815 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1816#define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1817#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1818#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1819#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1820#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1821#elif defined(__fallthrough) /* SAL */
1822#define JSON_HEDLEY_FALL_THROUGH __fallthrough
1823#else
1824#define JSON_HEDLEY_FALL_THROUGH
1825#endif
1826
1827#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1828#undef JSON_HEDLEY_RETURNS_NON_NULL
1829#endif
1830#if \
1831 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1832 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1833 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1834#define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1835#elif defined(_Ret_notnull_) /* SAL */
1836#define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1837#else
1838#define JSON_HEDLEY_RETURNS_NON_NULL
1839#endif
1840
1841#if defined(JSON_HEDLEY_ARRAY_PARAM)
1842#undef JSON_HEDLEY_ARRAY_PARAM
1843#endif
1844#if \
1845 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1846 !defined(__STDC_NO_VLA__) && \
1847 !defined(__cplusplus) && \
1848 !defined(JSON_HEDLEY_PGI_VERSION) && \
1849 !defined(JSON_HEDLEY_TINYC_VERSION)
1850#define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1851#else
1852#define JSON_HEDLEY_ARRAY_PARAM(name)
1853#endif
1854
1855#if defined(JSON_HEDLEY_IS_CONSTANT)
1856#undef JSON_HEDLEY_IS_CONSTANT
1857#endif
1858#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1859#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1860#endif
1861 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1862 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1863#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1864#undef JSON_HEDLEY_IS_CONSTEXPR_
1865#endif
1866#if \
1867 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1868 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1869 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1870 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1871 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1872 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1873 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1874 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1875 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1876 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1878#endif
1879#if !defined(__cplusplus)
1880# if \
1881 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1882 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1883 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1884 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1885 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1886 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1887 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1888#if defined(__INTPTR_TYPE__)
1889#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1890#else
1891#include <stdint.h>
1892#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1893#endif
1894# elif \
1895 ( \
1896 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1897 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1898 !defined(JSON_HEDLEY_PGI_VERSION) && \
1899 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1900 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1901 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1902 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1903 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1904 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1905#if defined(__INTPTR_TYPE__)
1906#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1907#else
1908#include <stdint.h>
1909#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1910#endif
1911# elif \
1912 defined(JSON_HEDLEY_GCC_VERSION) || \
1913 defined(JSON_HEDLEY_INTEL_VERSION) || \
1914 defined(JSON_HEDLEY_TINYC_VERSION) || \
1915 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1916 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1917 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1918 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1919 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1920 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1921 defined(__clang__)
1922# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1923 sizeof(void) != \
1924 sizeof(*( \
1925 1 ? \
1926 ((void*) ((expr) * 0L) ) : \
1927((struct { char v[sizeof(void) * 2]; } *) 1) \
1928 ) \
1929 ) \
1930 )
1931# endif
1932#endif
1933#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1934#if !defined(JSON_HEDLEY_IS_CONSTANT)
1935#define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1936#endif
1937#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1938#else
1939#if !defined(JSON_HEDLEY_IS_CONSTANT)
1940#define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1941#endif
1942#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1943#endif
1944
1945#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1946#undef JSON_HEDLEY_BEGIN_C_DECLS
1947#endif
1948#if defined(JSON_HEDLEY_END_C_DECLS)
1949#undef JSON_HEDLEY_END_C_DECLS
1950#endif
1951#if defined(JSON_HEDLEY_C_DECL)
1952#undef JSON_HEDLEY_C_DECL
1953#endif
1954#if defined(__cplusplus)
1955#define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1956#define JSON_HEDLEY_END_C_DECLS }
1957#define JSON_HEDLEY_C_DECL extern "C"
1958#else
1959#define JSON_HEDLEY_BEGIN_C_DECLS
1960#define JSON_HEDLEY_END_C_DECLS
1961#define JSON_HEDLEY_C_DECL
1962#endif
1963
1964#if defined(JSON_HEDLEY_STATIC_ASSERT)
1965#undef JSON_HEDLEY_STATIC_ASSERT
1966#endif
1967#if \
1968 !defined(__cplusplus) && ( \
1969 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1970 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1971 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1972 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1973 defined(_Static_assert) \
1974 )
1975# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1976#elif \
1977 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1978 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
1979 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1980# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1981#else
1982# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1983#endif
1984
1985#if defined(JSON_HEDLEY_NULL)
1986#undef JSON_HEDLEY_NULL
1987#endif
1988#if defined(__cplusplus)
1989#if __cplusplus >= 201103L
1990#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1991#elif defined(NULL)
1992#define JSON_HEDLEY_NULL NULL
1993#else
1994#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1995#endif
1996#elif defined(NULL)
1997#define JSON_HEDLEY_NULL NULL
1998#else
1999#define JSON_HEDLEY_NULL ((void*) 0)
2000#endif
2001
2002#if defined(JSON_HEDLEY_MESSAGE)
2003#undef JSON_HEDLEY_MESSAGE
2004#endif
2005#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2006# define JSON_HEDLEY_MESSAGE(msg) \
2007 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2008 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2009 JSON_HEDLEY_PRAGMA(message msg) \
2010 JSON_HEDLEY_DIAGNOSTIC_POP
2011#elif \
2012 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2013 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2014# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2015#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2016# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2017#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2018# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2019#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2020# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2021#else
2022# define JSON_HEDLEY_MESSAGE(msg)
2023#endif
2024
2025#if defined(JSON_HEDLEY_WARNING)
2026#undef JSON_HEDLEY_WARNING
2027#endif
2028#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2029# define JSON_HEDLEY_WARNING(msg) \
2030 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2031 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2032 JSON_HEDLEY_PRAGMA(clang warning msg) \
2033 JSON_HEDLEY_DIAGNOSTIC_POP
2034#elif \
2035 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2036 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2037 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2038# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2039#elif \
2040 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2041 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2042# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2043#else
2044# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2045#endif
2046
2047#if defined(JSON_HEDLEY_REQUIRE)
2048#undef JSON_HEDLEY_REQUIRE
2049#endif
2050#if defined(JSON_HEDLEY_REQUIRE_MSG)
2051#undef JSON_HEDLEY_REQUIRE_MSG
2052#endif
2053#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2054# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2055# define JSON_HEDLEY_REQUIRE(expr) \
2056 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2057 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2058 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2059 JSON_HEDLEY_DIAGNOSTIC_POP
2060# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2061 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2062 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2063 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2064 JSON_HEDLEY_DIAGNOSTIC_POP
2065# else
2066# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2067# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2068# endif
2069#else
2070# define JSON_HEDLEY_REQUIRE(expr)
2071# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2072#endif
2073
2074#if defined(JSON_HEDLEY_FLAGS)
2075#undef JSON_HEDLEY_FLAGS
2076#endif
2077#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2078#define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2079#else
2080#define JSON_HEDLEY_FLAGS
2081#endif
2082
2083#if defined(JSON_HEDLEY_FLAGS_CAST)
2084#undef JSON_HEDLEY_FLAGS_CAST
2085#endif
2086#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2087# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2088 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2089 _Pragma("warning(disable:188)") \
2090 ((T) (expr)); \
2091 JSON_HEDLEY_DIAGNOSTIC_POP \
2092 }))
2093#else
2094# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2095#endif
2096
2097#if defined(JSON_HEDLEY_EMPTY_BASES)
2098#undef JSON_HEDLEY_EMPTY_BASES
2099#endif
2100#if \
2101 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2102 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2104#else
2105#define JSON_HEDLEY_EMPTY_BASES
2106#endif
2107
2108 /* Remaining macros are deprecated. */
2109
2110#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2111#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2112#endif
2113#if defined(__clang__)
2114#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2115#else
2116#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2117#endif
2118
2119#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2120#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2121#endif
2122#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2123
2124#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2125#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2126#endif
2127#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2128
2129#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2130#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2131#endif
2132#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2133
2134#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2135#undef JSON_HEDLEY_CLANG_HAS_FEATURE
2136#endif
2137#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2138
2139#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2140#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2141#endif
2142#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2143
2144#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2145#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2146#endif
2147#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2148
2149#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2150#undef JSON_HEDLEY_CLANG_HAS_WARNING
2151#endif
2152#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2153
2154#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2155
2156// #include <nlohmann/detail/meta/detected.hpp>
2157
2158
2159#include <type_traits>
2160
2161// #include <nlohmann/detail/meta/void_t.hpp>
2162
2163
2164namespace nlohmann
2165{
2166 namespace detail
2167 {
2168 template<typename ...Ts> struct make_void
2169 {
2170 using type = void;
2171 };
2172 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2173 } // namespace detail
2174} // namespace nlohmann
2175
2176
2177// https://en.cppreference.com/w/cpp/experimental/is_detected
2178namespace nlohmann
2179{
2180 namespace detail
2181 {
2183 {
2184 nonesuch() = delete;
2185 ~nonesuch() = delete;
2186 nonesuch(nonesuch const&) = delete;
2187 nonesuch(nonesuch const&&) = delete;
2188 void operator=(nonesuch const&) = delete;
2189 void operator=(nonesuch&&) = delete;
2190 };
2191
2192 template<class Default,
2193 class AlwaysVoid,
2194 template<class...> class Op,
2195 class... Args>
2197 {
2198 using value_t = std::false_type;
2199 using type = Default;
2200 };
2201
2202 template<class Default, template<class...> class Op, class... Args>
2203 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2204 {
2205 using value_t = std::true_type;
2206 using type = Op<Args...>;
2207 };
2208
2209 template<template<class...> class Op, class... Args>
2210 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2211
2212 template<template<class...> class Op, class... Args>
2213 struct is_detected_lazy : is_detected<Op, Args...> { };
2214
2215 template<template<class...> class Op, class... Args>
2216 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2217
2218 template<class Default, template<class...> class Op, class... Args>
2219 using detected_or = detector<Default, void, Op, Args...>;
2220
2221 template<class Default, template<class...> class Op, class... Args>
2222 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2223
2224 template<class Expected, template<class...> class Op, class... Args>
2225 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2226
2227 template<class To, template<class...> class Op, class... Args>
2229 std::is_convertible<detected_t<Op, Args...>, To>;
2230 } // namespace detail
2231} // namespace nlohmann
2232
2233
2234// This file contains all internal macro definitions
2235// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2236
2237// exclude unsupported compilers
2238#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2239#if defined(__clang__)
2240#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2241#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2242#endif
2243#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2244#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2245#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2246#endif
2247#endif
2248#endif
2249
2250// C++ language standard detection
2251// if the user manually specified the used c++ version this is skipped
2252#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2253#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2254#define JSON_HAS_CPP_20
2255#define JSON_HAS_CPP_17
2256#define JSON_HAS_CPP_14
2257#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2258#define JSON_HAS_CPP_17
2259#define JSON_HAS_CPP_14
2260#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2261#define JSON_HAS_CPP_14
2262#endif
2263// the cpp 11 flag is always specified because it is the minimal required version
2264#define JSON_HAS_CPP_11
2265#endif
2266
2267#ifdef __has_include
2268#if __has_include(<version>)
2269#include <version>
2270#endif
2271#endif
2272
2273#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2274#ifdef JSON_HAS_CPP_17
2275#if defined(__cpp_lib_filesystem)
2276#define JSON_HAS_FILESYSTEM 1
2277#elif defined(__cpp_lib_experimental_filesystem)
2278#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2279#elif !defined(__has_include)
2280#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2281#elif __has_include(<filesystem>)
2282#define JSON_HAS_FILESYSTEM 1
2283#elif __has_include(<experimental/filesystem>)
2284#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2285#endif
2286
2287// std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2288#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2289#undef JSON_HAS_FILESYSTEM
2290#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2291#endif
2292
2293// no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2294#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2295#undef JSON_HAS_FILESYSTEM
2296#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2297#endif
2298
2299// no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2300#if defined(__clang_major__) && __clang_major__ < 7
2301#undef JSON_HAS_FILESYSTEM
2302#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2303#endif
2304
2305// no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2306#if defined(_MSC_VER) && _MSC_VER < 1914
2307#undef JSON_HAS_FILESYSTEM
2308#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2309#endif
2310
2311// no filesystem support before iOS 13
2312#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2313#undef JSON_HAS_FILESYSTEM
2314#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2315#endif
2316
2317// no filesystem support before macOS Catalina
2318#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2319#undef JSON_HAS_FILESYSTEM
2320#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2321#endif
2322#endif
2323#endif
2324
2325#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2326#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2327#endif
2328
2329#ifndef JSON_HAS_FILESYSTEM
2330#define JSON_HAS_FILESYSTEM 0
2331#endif
2332
2333#ifndef JSON_HAS_THREE_WAY_COMPARISON
2334#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2335 && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2336#define JSON_HAS_THREE_WAY_COMPARISON 1
2337#else
2338#define JSON_HAS_THREE_WAY_COMPARISON 0
2339#endif
2340#endif
2341
2342#ifndef JSON_HAS_RANGES
2343 // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2344#if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2345#define JSON_HAS_RANGES 0
2346#elif defined(__cpp_lib_ranges)
2347#define JSON_HAS_RANGES 1
2348#else
2349#define JSON_HAS_RANGES 0
2350#endif
2351#endif
2352
2353#ifdef JSON_HAS_CPP_17
2354#define JSON_INLINE_VARIABLE inline
2355#else
2356#define JSON_INLINE_VARIABLE
2357#endif
2358
2359#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2360#define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2361#else
2362#define JSON_NO_UNIQUE_ADDRESS
2363#endif
2364
2365// disable documentation warnings on clang
2366#if defined(__clang__)
2367#pragma clang diagnostic push
2368#pragma clang diagnostic ignored "-Wdocumentation"
2369#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2370#endif
2371
2372// allow disabling exceptions
2373#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2374#define JSON_THROW(exception) throw exception
2375#define JSON_TRY try
2376#define JSON_CATCH(exception) catch(exception)
2377#define JSON_INTERNAL_CATCH(exception) catch(exception)
2378#else
2379#include <cstdlib>
2380#define JSON_THROW(exception) std::abort()
2381#define JSON_TRY if(true)
2382#define JSON_CATCH(exception) if(false)
2383#define JSON_INTERNAL_CATCH(exception) if(false)
2384#endif
2385
2386// override exception macros
2387#if defined(JSON_THROW_USER)
2388#undef JSON_THROW
2389#define JSON_THROW JSON_THROW_USER
2390#endif
2391#if defined(JSON_TRY_USER)
2392#undef JSON_TRY
2393#define JSON_TRY JSON_TRY_USER
2394#endif
2395#if defined(JSON_CATCH_USER)
2396#undef JSON_CATCH
2397#define JSON_CATCH JSON_CATCH_USER
2398#undef JSON_INTERNAL_CATCH
2399#define JSON_INTERNAL_CATCH JSON_CATCH_USER
2400#endif
2401#if defined(JSON_INTERNAL_CATCH_USER)
2402#undef JSON_INTERNAL_CATCH
2403#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2404#endif
2405
2406// allow overriding assert
2407#if !defined(JSON_ASSERT)
2408#include <cassert> // assert
2409#define JSON_ASSERT(x) assert(x)
2410#endif
2411
2412// allow to access some private functions (needed by the test suite)
2413#if defined(JSON_TESTS_PRIVATE)
2414#define JSON_PRIVATE_UNLESS_TESTED public
2415#else
2416#define JSON_PRIVATE_UNLESS_TESTED private
2417#endif
2418
2424#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2425 template<typename BasicJsonType> \
2426 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2427 { \
2428 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2429 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2430 auto it = std::find_if(std::begin(m), std::end(m), \
2431 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2432 { \
2433 return ej_pair.first == e; \
2434 }); \
2435 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2436 } \
2437 template<typename BasicJsonType> \
2438 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2439 { \
2440 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2441 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2442 auto it = std::find_if(std::begin(m), std::end(m), \
2443 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2444 { \
2445 return ej_pair.second == j; \
2446 }); \
2447 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2448 }
2449
2450// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2451// may be removed in the future once the class is split.
2452
2453#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2454 template<template<typename, typename, typename...> class ObjectType, \
2455 template<typename, typename...> class ArrayType, \
2456 class StringType, class BooleanType, class NumberIntegerType, \
2457 class NumberUnsignedType, class NumberFloatType, \
2458 template<typename> class AllocatorType, \
2459 template<typename, typename = void> class JSONSerializer, \
2460 class BinaryType>
2461
2462#define NLOHMANN_BASIC_JSON_TPL \
2463 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2464 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2465 AllocatorType, JSONSerializer, BinaryType>
2466
2467// Macros to simplify conversion from/to types
2468
2469#define NLOHMANN_JSON_EXPAND( x ) x
2470#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2471#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2472 NLOHMANN_JSON_PASTE64, \
2473 NLOHMANN_JSON_PASTE63, \
2474 NLOHMANN_JSON_PASTE62, \
2475 NLOHMANN_JSON_PASTE61, \
2476 NLOHMANN_JSON_PASTE60, \
2477 NLOHMANN_JSON_PASTE59, \
2478 NLOHMANN_JSON_PASTE58, \
2479 NLOHMANN_JSON_PASTE57, \
2480 NLOHMANN_JSON_PASTE56, \
2481 NLOHMANN_JSON_PASTE55, \
2482 NLOHMANN_JSON_PASTE54, \
2483 NLOHMANN_JSON_PASTE53, \
2484 NLOHMANN_JSON_PASTE52, \
2485 NLOHMANN_JSON_PASTE51, \
2486 NLOHMANN_JSON_PASTE50, \
2487 NLOHMANN_JSON_PASTE49, \
2488 NLOHMANN_JSON_PASTE48, \
2489 NLOHMANN_JSON_PASTE47, \
2490 NLOHMANN_JSON_PASTE46, \
2491 NLOHMANN_JSON_PASTE45, \
2492 NLOHMANN_JSON_PASTE44, \
2493 NLOHMANN_JSON_PASTE43, \
2494 NLOHMANN_JSON_PASTE42, \
2495 NLOHMANN_JSON_PASTE41, \
2496 NLOHMANN_JSON_PASTE40, \
2497 NLOHMANN_JSON_PASTE39, \
2498 NLOHMANN_JSON_PASTE38, \
2499 NLOHMANN_JSON_PASTE37, \
2500 NLOHMANN_JSON_PASTE36, \
2501 NLOHMANN_JSON_PASTE35, \
2502 NLOHMANN_JSON_PASTE34, \
2503 NLOHMANN_JSON_PASTE33, \
2504 NLOHMANN_JSON_PASTE32, \
2505 NLOHMANN_JSON_PASTE31, \
2506 NLOHMANN_JSON_PASTE30, \
2507 NLOHMANN_JSON_PASTE29, \
2508 NLOHMANN_JSON_PASTE28, \
2509 NLOHMANN_JSON_PASTE27, \
2510 NLOHMANN_JSON_PASTE26, \
2511 NLOHMANN_JSON_PASTE25, \
2512 NLOHMANN_JSON_PASTE24, \
2513 NLOHMANN_JSON_PASTE23, \
2514 NLOHMANN_JSON_PASTE22, \
2515 NLOHMANN_JSON_PASTE21, \
2516 NLOHMANN_JSON_PASTE20, \
2517 NLOHMANN_JSON_PASTE19, \
2518 NLOHMANN_JSON_PASTE18, \
2519 NLOHMANN_JSON_PASTE17, \
2520 NLOHMANN_JSON_PASTE16, \
2521 NLOHMANN_JSON_PASTE15, \
2522 NLOHMANN_JSON_PASTE14, \
2523 NLOHMANN_JSON_PASTE13, \
2524 NLOHMANN_JSON_PASTE12, \
2525 NLOHMANN_JSON_PASTE11, \
2526 NLOHMANN_JSON_PASTE10, \
2527 NLOHMANN_JSON_PASTE9, \
2528 NLOHMANN_JSON_PASTE8, \
2529 NLOHMANN_JSON_PASTE7, \
2530 NLOHMANN_JSON_PASTE6, \
2531 NLOHMANN_JSON_PASTE5, \
2532 NLOHMANN_JSON_PASTE4, \
2533 NLOHMANN_JSON_PASTE3, \
2534 NLOHMANN_JSON_PASTE2, \
2535 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2536#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2537#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2538#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2539#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2540#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2541#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2542#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2543#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2544#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2545#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2546#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2547#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2548#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2549#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2550#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2551#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2552#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2553#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2554#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2555#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2556#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2557#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2558#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2559#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2560#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2561#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2562#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2563#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2564#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2565#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2566#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2567#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2568#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2569#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2570#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2571#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2572#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2573#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2574#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2575#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2576#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2577#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2578#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2579#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2580#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2581#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2582#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2583#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2584#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2585#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2586#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2587#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2588#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2589#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2590#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2591#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2592#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2593#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2594#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2595#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2596#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2597#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2598#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2599
2600#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2601#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2602#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2603
2609#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2610 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2611 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2612
2613#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2614 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2615 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2616
2622#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2623 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2624 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2625
2626#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2627 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2628 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2629
2630
2631// inspired from https://stackoverflow.com/a/26745591
2632// allows to call any std function as if (e.g. with begin):
2633// using std::begin; begin(x);
2634//
2635// it allows using the detected idiom to retrieve the return type
2636// of such an expression
2637#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2638 namespace detail { \
2639 using std::std_name; \
2640 \
2641 template<typename... T> \
2642 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2643 } \
2644 \
2645 namespace detail2 { \
2646 struct std_name##_tag \
2647 { \
2648 }; \
2649 \
2650 template<typename... T> \
2651 std_name##_tag std_name(T&&...); \
2652 \
2653 template<typename... T> \
2654 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2655 \
2656 template<typename... T> \
2657 struct would_call_std_##std_name \
2658 { \
2659 static constexpr auto const value = ::nlohmann::detail:: \
2660 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2661 }; \
2662 } /* namespace detail2 */ \
2663 \
2664 template<typename... T> \
2665 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2666 { \
2667 }
2668
2669#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2670#define JSON_USE_IMPLICIT_CONVERSIONS 1
2671#endif
2672
2673#if JSON_USE_IMPLICIT_CONVERSIONS
2674#define JSON_EXPLICIT
2675#else
2676#define JSON_EXPLICIT explicit
2677#endif
2678
2679#ifndef JSON_DIAGNOSTICS
2680#define JSON_DIAGNOSTICS 0
2681#endif
2682
2683#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
2684#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
2685#endif
2686
2687#if JSON_HAS_THREE_WAY_COMPARISON
2688#include <compare> // partial_ordering
2689#endif
2690
2691namespace nlohmann
2692{
2693 namespace detail
2694 {
2696 // JSON type enumeration //
2698
2723 enum class value_t : std::uint8_t
2724 {
2725 null,
2726 object,
2727 array,
2728 string,
2729 boolean,
2732 number_float,
2733 binary,
2734 discarded
2735 };
2736
2750#if JSON_HAS_THREE_WAY_COMPARISON
2751 inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2752#else
2753 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2754#endif
2755 {
2756 static constexpr std::array<std::uint8_t, 9> order = { {
2757 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2758 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2759 6 /* binary */
2760 }
2761 };
2762
2763 const auto l_index = static_cast<std::size_t>(lhs);
2764 const auto r_index = static_cast<std::size_t>(rhs);
2765#if JSON_HAS_THREE_WAY_COMPARISON
2766 if (l_index < order.size() && r_index < order.size())
2767 {
2768 return order[l_index] <=> order[r_index]; // *NOPAD*
2769 }
2770 return std::partial_ordering::unordered;
2771#else
2772 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2773#endif
2774 }
2775
2776 // GCC selects the built-in operator< over an operator rewritten from
2777 // a user-defined spaceship operator
2778 // Clang, MSVC, and ICC select the rewritten candidate
2779 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2780#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2781 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2782 {
2783 return std::is_lt(lhs <=> rhs); // *NOPAD*
2784 }
2785#endif
2786 } // namespace detail
2787} // namespace nlohmann
2788
2789// #include <nlohmann/detail/string_escape.hpp>
2790
2791
2792// #include <nlohmann/detail/macro_scope.hpp>
2793
2794
2795namespace nlohmann
2796{
2797 namespace detail
2798 {
2799
2813 template<typename StringType>
2814 inline void replace_substring(StringType& s, const StringType& f,
2815 const StringType& t)
2816 {
2817 JSON_ASSERT(!f.empty());
2818 for (auto pos = s.find(f); // find first occurrence of f
2819 pos != StringType::npos; // make sure f was found
2820 s.replace(pos, f.size(), t), // replace with t, and
2821 pos = s.find(f, pos + t.size())) // find next occurrence of f
2822 {
2823 }
2824 }
2825
2833 template<typename StringType>
2834 inline StringType escape(StringType s)
2835 {
2836 replace_substring(s, StringType{ "~" }, StringType{ "~0" });
2837 replace_substring(s, StringType{ "/" }, StringType{ "~1" });
2838 return s;
2839 }
2840
2848 template<typename StringType>
2849 static void unescape(StringType& s)
2850 {
2851 replace_substring(s, StringType{ "~1" }, StringType{ "/" });
2852 replace_substring(s, StringType{ "~0" }, StringType{ "~" });
2853 }
2854
2855 } // namespace detail
2856} // namespace nlohmann
2857
2858// #include <nlohmann/detail/input/position_t.hpp>
2859
2860
2861#include <cstddef> // size_t
2862
2863namespace nlohmann
2864{
2865 namespace detail
2866 {
2869 {
2871 std::size_t chars_read_total = 0;
2875 std::size_t lines_read = 0;
2876
2878 constexpr operator size_t() const
2879 {
2880 return chars_read_total;
2881 }
2882 };
2883
2884 } // namespace detail
2885} // namespace nlohmann
2886
2887// #include <nlohmann/detail/macro_scope.hpp>
2888
2889// #include <nlohmann/detail/meta/cpp_future.hpp>
2890
2891
2892#include <cstddef> // size_t
2893#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2894#include <utility> // index_sequence, make_index_sequence, index_sequence_for
2895
2896// #include <nlohmann/detail/macro_scope.hpp>
2897
2898
2899namespace nlohmann
2900{
2901 namespace detail
2902 {
2903
2904 template<typename T>
2905 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2906
2907#ifdef JSON_HAS_CPP_14
2908
2909 // the following utilities are natively available in C++14
2910 using std::enable_if_t;
2911 using std::index_sequence;
2914
2915#else
2916
2917 // alias templates to reduce boilerplate
2918 template<bool B, typename T = void>
2919 using enable_if_t = typename std::enable_if<B, T>::type;
2920
2921 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
2922 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
2923
2925
2926 // integer_sequence
2927 //
2928 // Class template representing a compile-time integer sequence. An instantiation
2929 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
2930 // type through its template arguments (which is a common need when
2931 // working with C++11 variadic templates). `absl::integer_sequence` is designed
2932 // to be a drop-in replacement for C++14's `std::integer_sequence`.
2933 //
2934 // Example:
2935 //
2936 // template< class T, T... Ints >
2937 // void user_function(integer_sequence<T, Ints...>);
2938 //
2939 // int main()
2940 // {
2941 // // user_function's `T` will be deduced to `int` and `Ints...`
2942 // // will be deduced to `0, 1, 2, 3, 4`.
2943 // user_function(make_integer_sequence<int, 5>());
2944 // }
2945 template <typename T, T... Ints>
2947 {
2948 using value_type = T;
2949 static constexpr std::size_t size() noexcept
2950 {
2951 return sizeof...(Ints);
2952 }
2953 };
2954
2955 // index_sequence
2956 //
2957 // A helper template for an `integer_sequence` of `size_t`,
2958 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
2959 // `std::index_sequence`.
2960 template <size_t... Ints>
2961 using index_sequence = integer_sequence<size_t, Ints...>;
2962
2963 namespace utility_internal
2964 {
2965
2966 template <typename Seq, size_t SeqSize, size_t Rem>
2967 struct Extend;
2968
2969 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
2970 template <typename T, T... Ints, size_t SeqSize>
2971 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
2972 {
2973 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
2974 };
2975
2976 template <typename T, T... Ints, size_t SeqSize>
2977 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
2978 {
2979 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
2980 };
2981
2982 // Recursion helper for 'make_integer_sequence<T, N>'.
2983 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
2984 template <typename T, size_t N>
2985 struct Gen
2986 {
2987 using type =
2988 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
2989 };
2990
2991 template <typename T>
2992 struct Gen<T, 0>
2993 {
2995 };
2996
2997 } // namespace utility_internal
2998
2999 // Compile-time sequences of integers
3000
3001 // make_integer_sequence
3002 //
3003 // This template alias is equivalent to
3004 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3005 // replacement for C++14's `std::make_integer_sequence`.
3006 template <typename T, T N>
3008
3009 // make_index_sequence
3010 //
3011 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3012 // and is designed to be a drop-in replacement for C++14's
3013 // `std::make_index_sequence`.
3014 template <size_t N>
3016
3017 // index_sequence_for
3018 //
3019 // Converts a typename pack into an index sequence of the same length, and
3020 // is designed to be a drop-in replacement for C++14's
3021 // `std::index_sequence_for()`
3022 template <typename... Ts>
3024
3026
3027#endif
3028
3029// dispatch utility (taken from ranges-v3)
3030 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3031 template<> struct priority_tag<0> {};
3032
3033 // taken from ranges-v3
3034 template<typename T>
3036 {
3037 static constexpr T value{};
3038 };
3039
3040#ifndef JSON_HAS_CPP_17
3041
3042 template<typename T>
3043 constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
3044
3045#endif
3046
3047 } // namespace detail
3048} // namespace nlohmann
3049
3050// #include <nlohmann/detail/meta/type_traits.hpp>
3051
3052
3053#include <limits> // numeric_limits
3054#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3055#include <utility> // declval
3056#include <tuple> // tuple
3057
3058// #include <nlohmann/detail/macro_scope.hpp>
3059
3060
3061// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3062
3063
3064#include <iterator> // random_access_iterator_tag
3065
3066// #include <nlohmann/detail/meta/void_t.hpp>
3067
3068// #include <nlohmann/detail/meta/cpp_future.hpp>
3069
3070
3071namespace nlohmann
3072{
3073 namespace detail
3074 {
3075 template<typename It, typename = void>
3077
3078 template<typename It>
3080 It,
3081 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3082 typename It::reference, typename It::iterator_category >>
3083 {
3084 using difference_type = typename It::difference_type;
3085 using value_type = typename It::value_type;
3086 using pointer = typename It::pointer;
3087 using reference = typename It::reference;
3088 using iterator_category = typename It::iterator_category;
3089 };
3090
3091 // This is required as some compilers implement std::iterator_traits in a way that
3092 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3093 template<typename T, typename = void>
3095 {
3096 };
3097
3098 template<typename T>
3099 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3100 : iterator_types<T>
3101 {
3102 };
3103
3104 template<typename T>
3106 {
3107 using iterator_category = std::random_access_iterator_tag;
3108 using value_type = T;
3109 using difference_type = ptrdiff_t;
3110 using pointer = T*;
3111 using reference = T&;
3112 };
3113 } // namespace detail
3114} // namespace nlohmann
3115
3116// #include <nlohmann/detail/meta/call_std/begin.hpp>
3117
3118
3119// #include <nlohmann/detail/macro_scope.hpp>
3120
3121
3122namespace nlohmann
3123{
3125} // namespace nlohmann
3126
3127// #include <nlohmann/detail/meta/call_std/end.hpp>
3128
3129
3130// #include <nlohmann/detail/macro_scope.hpp>
3131
3132
3133namespace nlohmann
3134{
3136} // namespace nlohmann
3137
3138// #include <nlohmann/detail/meta/cpp_future.hpp>
3139
3140// #include <nlohmann/detail/meta/detected.hpp>
3141
3142// #include <nlohmann/json_fwd.hpp>
3143#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3144#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3145
3146#include <cstdint> // int64_t, uint64_t
3147#include <map> // map
3148#include <memory> // allocator
3149#include <string> // string
3150#include <vector> // vector
3151
3157namespace nlohmann
3158{
3166 template<typename T = void, typename SFINAE = void>
3167 struct adl_serializer;
3168
3171 template<template<typename U, typename V, typename... Args> class ObjectType =
3172 std::map,
3173 template<typename U, typename... Args> class ArrayType = std::vector,
3174 class StringType = std::string, class BooleanType = bool,
3175 class NumberIntegerType = std::int64_t,
3176 class NumberUnsignedType = std::uint64_t,
3177 class NumberFloatType = double,
3178 template<typename U> class AllocatorType = std::allocator,
3179 template<typename T, typename SFINAE = void> class JSONSerializer =
3180 adl_serializer,
3181 class BinaryType = std::vector<std::uint8_t>>
3182 class basic_json;
3183
3186 template<typename BasicJsonType>
3187 class json_pointer;
3188
3194
3197 template<class Key, class T, class IgnoredLess, class Allocator>
3198 struct ordered_map;
3199
3203
3204} // namespace nlohmann
3205
3206#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3207
3208
3209namespace nlohmann
3210{
3219 namespace detail
3220 {
3222 // helpers //
3224
3225 // Note to maintainers:
3226 //
3227 // Every trait in this file expects a non CV-qualified type.
3228 // The only exceptions are in the 'aliases for detected' section
3229 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3230 //
3231 // In this case, T has to be properly CV-qualified to constraint the function arguments
3232 // (e.g. to_json(BasicJsonType&, const T&))
3233
3234 template<typename> struct is_basic_json : std::false_type {};
3235
3237 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3238
3239 // used by exceptions create() member functions
3240 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3241 // false_type otherwise
3242 template<typename BasicJsonContext>
3244 std::integral_constant < bool,
3245 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3246 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3247 {};
3248
3250 // json_ref helpers //
3252
3253 template<typename>
3254 class json_ref;
3255
3256 template<typename>
3257 struct is_json_ref : std::false_type {};
3258
3259 template<typename T>
3260 struct is_json_ref<json_ref<T>> : std::true_type {};
3261
3263 // aliases for detected //
3265
3266 template<typename T>
3267 using mapped_type_t = typename T::mapped_type;
3268
3269 template<typename T>
3270 using key_type_t = typename T::key_type;
3271
3272 template<typename T>
3273 using value_type_t = typename T::value_type;
3274
3275 template<typename T>
3276 using difference_type_t = typename T::difference_type;
3277
3278 template<typename T>
3279 using pointer_t = typename T::pointer;
3280
3281 template<typename T>
3282 using reference_t = typename T::reference;
3283
3284 template<typename T>
3285 using iterator_category_t = typename T::iterator_category;
3286
3287 template<typename T, typename... Args>
3288 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3289
3290 template<typename T, typename... Args>
3291 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3292
3293 template<typename T, typename U>
3294 using get_template_function = decltype(std::declval<T>().template get<U>());
3295
3296 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3297 template<typename BasicJsonType, typename T, typename = void>
3298 struct has_from_json : std::false_type {};
3299
3300 // trait checking if j.get<T> is valid
3301 // use this trait instead of std::is_constructible or std::is_convertible,
3302 // both rely on, or make use of implicit conversions, and thus fail when T
3303 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3304 template <typename BasicJsonType, typename T>
3306 {
3308 };
3309
3310 template<typename BasicJsonType, typename T>
3311 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3312 {
3313 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3314
3315 static constexpr bool value =
3317 const BasicJsonType&, T&>::value;
3318 };
3319
3320 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3321 // this overload is used for non-default-constructible user-defined-types
3322 template<typename BasicJsonType, typename T, typename = void>
3323 struct has_non_default_from_json : std::false_type {};
3324
3325 template<typename BasicJsonType, typename T>
3326 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3327 {
3328 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3329
3330 static constexpr bool value =
3332 const BasicJsonType&>::value;
3333 };
3334
3335 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3336 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3337 template<typename BasicJsonType, typename T, typename = void>
3338 struct has_to_json : std::false_type {};
3339
3340 template<typename BasicJsonType, typename T>
3341 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3342 {
3343 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3344
3345 static constexpr bool value =
3346 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3347 T>::value;
3348 };
3349
3350 template<typename T>
3351 using detect_key_compare = typename T::key_compare;
3352
3353 template<typename T>
3354 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3355
3356 // obtains the actual object key comparator
3357 template<typename BasicJsonType>
3359 {
3360 using object_t = typename BasicJsonType::object_t;
3361 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3362 using type = typename std::conditional < has_key_compare<object_t>::value,
3363 typename object_t::key_compare, object_comparator_t>::type;
3364 };
3365
3366 template<typename BasicJsonType>
3368
3370 // is_ functions //
3372
3373 // https://en.cppreference.com/w/cpp/types/conjunction
3374 template<class...> struct conjunction : std::true_type { };
3375 template<class B> struct conjunction<B> : B { };
3376 template<class B, class... Bn>
3377 struct conjunction<B, Bn...>
3378 : std::conditional<bool(B::value), conjunction<Bn...>, B>::type {};
3379
3380 // https://en.cppreference.com/w/cpp/types/negation
3381 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3382
3383 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3384 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3385 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3386 template <typename T>
3387 struct is_default_constructible : std::is_default_constructible<T> {};
3388
3389 template <typename T1, typename T2>
3390 struct is_default_constructible<std::pair<T1, T2>>
3391 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3392
3393 template <typename T1, typename T2>
3394 struct is_default_constructible<const std::pair<T1, T2>>
3395 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3396
3397 template <typename... Ts>
3398 struct is_default_constructible<std::tuple<Ts...>>
3399 : conjunction<is_default_constructible<Ts>...> {};
3400
3401 template <typename... Ts>
3402 struct is_default_constructible<const std::tuple<Ts...>>
3403 : conjunction<is_default_constructible<Ts>...> {};
3404
3405
3406 template <typename T, typename... Args>
3407 struct is_constructible : std::is_constructible<T, Args...> {};
3408
3409 template <typename T1, typename T2>
3410 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3411
3412 template <typename T1, typename T2>
3413 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3414
3415 template <typename... Ts>
3416 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3417
3418 template <typename... Ts>
3419 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3420
3421
3422 template<typename T, typename = void>
3423 struct is_iterator_traits : std::false_type {};
3424
3425 template<typename T>
3427 {
3428 private:
3429 using traits = iterator_traits<T>;
3430
3431 public:
3432 static constexpr auto value =
3438 };
3439
3440 template<typename T>
3442 {
3443 private:
3444 using t_ref = typename std::add_lvalue_reference<T>::type;
3445
3446 using iterator = detected_t<result_of_begin, t_ref>;
3447 using sentinel = detected_t<result_of_end, t_ref>;
3448
3449 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3450 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3451 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3452 static constexpr auto is_iterator_begin =
3454
3455 public:
3456 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3457 };
3458
3459 template<typename R>
3460 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3461
3462 template<typename T>
3464
3465 // The following implementation of is_complete_type is taken from
3466 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3467 // and is written by Xiang Fan who agreed to using it in this library.
3468
3469 template<typename T, typename = void>
3470 struct is_complete_type : std::false_type {};
3471
3472 template<typename T>
3473 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3474
3475 template<typename BasicJsonType, typename CompatibleObjectType,
3476 typename = void>
3477 struct is_compatible_object_type_impl : std::false_type {};
3478
3479 template<typename BasicJsonType, typename CompatibleObjectType>
3481 BasicJsonType, CompatibleObjectType,
3482 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3483 is_detected<key_type_t, CompatibleObjectType>::value >>
3484 {
3485 using object_t = typename BasicJsonType::object_t;
3486
3487 // macOS's is_constructible does not play well with nonesuch...
3488 static constexpr bool value =
3489 is_constructible<typename object_t::key_type,
3490 typename CompatibleObjectType::key_type>::value &&
3491 is_constructible<typename object_t::mapped_type,
3492 typename CompatibleObjectType::mapped_type>::value;
3493 };
3494
3495 template<typename BasicJsonType, typename CompatibleObjectType>
3497 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3498
3499 template<typename BasicJsonType, typename ConstructibleObjectType,
3500 typename = void>
3501 struct is_constructible_object_type_impl : std::false_type {};
3502
3503 template<typename BasicJsonType, typename ConstructibleObjectType>
3505 BasicJsonType, ConstructibleObjectType,
3506 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3507 is_detected<key_type_t, ConstructibleObjectType>::value >>
3508 {
3509 using object_t = typename BasicJsonType::object_t;
3510
3511 static constexpr bool value =
3513 (std::is_move_assignable<ConstructibleObjectType>::value ||
3514 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3515 (is_constructible<typename ConstructibleObjectType::key_type,
3516 typename object_t::key_type>::value &&
3517 std::is_same <
3518 typename object_t::mapped_type,
3519 typename ConstructibleObjectType::mapped_type >::value)) ||
3520 (has_from_json<BasicJsonType,
3521 typename ConstructibleObjectType::mapped_type>::value ||
3523 BasicJsonType,
3524 typename ConstructibleObjectType::mapped_type >::value);
3525 };
3526
3527 template<typename BasicJsonType, typename ConstructibleObjectType>
3529 : is_constructible_object_type_impl<BasicJsonType,
3530 ConstructibleObjectType> {};
3531
3532 template<typename BasicJsonType, typename CompatibleStringType>
3534 {
3535 static constexpr auto value =
3537 };
3538
3539 template<typename BasicJsonType, typename ConstructibleStringType>
3541 {
3542 // launder type through decltype() to fix compilation failure on ICPC
3543#ifdef __INTEL_COMPILER
3544 using laundered_type = decltype(std::declval<ConstructibleStringType>());
3545#else
3546 using laundered_type = ConstructibleStringType;
3547#endif
3548
3549 static constexpr auto value =
3551 typename BasicJsonType::string_t>::value;
3552 };
3553
3554 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3555 struct is_compatible_array_type_impl : std::false_type {};
3556
3557 template<typename BasicJsonType, typename CompatibleArrayType>
3559 BasicJsonType, CompatibleArrayType,
3560 enable_if_t <
3561 is_detected<iterator_t, CompatibleArrayType>::value&&
3562 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value &&
3563 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3564 // c.f. https://github.com/nlohmann/json/pull/3073
3565 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3566 {
3567 static constexpr bool value =
3568 is_constructible<BasicJsonType,
3570 };
3571
3572 template<typename BasicJsonType, typename CompatibleArrayType>
3574 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3575
3576 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3577 struct is_constructible_array_type_impl : std::false_type {};
3578
3579 template<typename BasicJsonType, typename ConstructibleArrayType>
3581 BasicJsonType, ConstructibleArrayType,
3582 enable_if_t<std::is_same<ConstructibleArrayType,
3583 typename BasicJsonType::value_type>::value >>
3584 : std::true_type {};
3585
3586 template<typename BasicJsonType, typename ConstructibleArrayType>
3588 BasicJsonType, ConstructibleArrayType,
3589 enable_if_t < !std::is_same<ConstructibleArrayType,
3590 typename BasicJsonType::value_type>::value &&
3591 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3592 is_default_constructible<ConstructibleArrayType>::value &&
3593 (std::is_move_assignable<ConstructibleArrayType>::value ||
3594 std::is_copy_assignable<ConstructibleArrayType>::value) &&
3595 is_detected<iterator_t, ConstructibleArrayType>::value&&
3596 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3597 is_detected<range_value_t, ConstructibleArrayType>::value &&
3598 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3599 // c.f. https://github.com/nlohmann/json/pull/3073
3600 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3602 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3603 {
3605
3606 static constexpr bool value =
3607 std::is_same<value_type,
3608 typename BasicJsonType::array_t::value_type>::value ||
3609 has_from_json<BasicJsonType,
3610 value_type>::value ||
3612 BasicJsonType,
3613 value_type >::value;
3614 };
3615
3616 template<typename BasicJsonType, typename ConstructibleArrayType>
3618 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3619
3620 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3621 typename = void>
3622 struct is_compatible_integer_type_impl : std::false_type {};
3623
3624 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3626 RealIntegerType, CompatibleNumberIntegerType,
3627 enable_if_t < std::is_integral<RealIntegerType>::value&&
3628 std::is_integral<CompatibleNumberIntegerType>::value &&
3629 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3630 {
3631 // is there an assert somewhere on overflows?
3632 using RealLimits = std::numeric_limits<RealIntegerType>;
3633 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3634
3635 static constexpr auto value =
3636 is_constructible<RealIntegerType,
3637 CompatibleNumberIntegerType>::value &&
3638 CompatibleLimits::is_integer &&
3639 RealLimits::is_signed == CompatibleLimits::is_signed;
3640 };
3641
3642 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3644 : is_compatible_integer_type_impl<RealIntegerType,
3645 CompatibleNumberIntegerType> {};
3646
3647 template<typename BasicJsonType, typename CompatibleType, typename = void>
3648 struct is_compatible_type_impl : std::false_type {};
3649
3650 template<typename BasicJsonType, typename CompatibleType>
3652 BasicJsonType, CompatibleType,
3653 enable_if_t<is_complete_type<CompatibleType>::value >>
3654 {
3655 static constexpr bool value =
3657 };
3658
3659 template<typename BasicJsonType, typename CompatibleType>
3661 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3662
3663 template<typename T1, typename T2>
3664 struct is_constructible_tuple : std::false_type {};
3665
3666 template<typename T1, typename... Args>
3667 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3668
3669 template<typename BasicJsonType, typename T>
3670 struct is_json_iterator_of : std::false_type {};
3671
3672 template<typename BasicJsonType>
3673 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3674
3675 template<typename BasicJsonType>
3676 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3677 {};
3678
3679 // checks if a given type T is a template specialization of Primary
3680 template<template <typename...> class Primary, typename T>
3681 struct is_specialization_of : std::false_type {};
3682
3683 template<template <typename...> class Primary, typename... Args>
3684 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3685
3686 template<typename T>
3688
3689 // checks if A and B are comparable using Compare functor
3690 template<typename Compare, typename A, typename B, typename = void>
3691 struct is_comparable : std::false_type {};
3692
3693 template<typename Compare, typename A, typename B>
3694 struct is_comparable<Compare, A, B, void_t<
3695 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3696 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3697 >> : std::true_type {};
3698
3699 // checks if BasicJsonType::object_t::key_type and KeyType are comparable using Compare functor
3700 template<typename BasicJsonType, typename KeyType>
3702 typename BasicJsonType::object_comparator_t,
3704 KeyType >::type;
3705
3706 template<typename T>
3707 using detect_is_transparent = typename T::is_transparent;
3708
3709 // type trait to check if KeyType can be used as object key
3710 // true if:
3711 // - KeyType is comparable with BasicJsonType::object_t::key_type
3712 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3713 // - the comparator is transparent or RequireTransparentComparator is false
3714 // - KeyType is not a JSON iterator or json_pointer
3715 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3716 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3717 using is_usable_as_key_type = typename std::conditional <
3719 && !(ExcludeObjectKeyType&& std::is_same<KeyType,
3720 typename BasicJsonType::object_t::key_type>::value)
3721 && (!RequireTransparentComparator || is_detected <
3723 typename BasicJsonType::object_comparator_t >::value)
3726 std::true_type,
3727 std::false_type >::type;
3728
3729 template<typename ObjectType, typename KeyType>
3730 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3731
3732 // type trait to check if object_t has an erase() member functions accepting KeyType
3733 template<typename BasicJsonType, typename KeyType>
3734 using has_erase_with_key_type = typename std::conditional <
3735 is_detected <
3737 typename BasicJsonType::object_t, KeyType >::value,
3738 std::true_type,
3739 std::false_type >::type;
3740
3741 // a naive helper to check if a type is an ordered_map (exploits the fact that
3742 // ordered_map inherits capacity() from std::vector)
3743 template <typename T>
3745 {
3746 using one = char;
3747
3748 struct two
3749 {
3750 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3751 };
3752
3753 template <typename C> static one test(decltype(&C::capacity));
3754 template <typename C> static two test(...);
3755
3756 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3757 };
3758
3759 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3760 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3762 {
3763 return static_cast<T>(value);
3764 }
3765
3766 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3767 T conditional_static_cast(U value)
3768 {
3769 return value;
3770 }
3771
3772 } // namespace detail
3773} // namespace nlohmann
3774
3775// #include <nlohmann/detail/string_concat.hpp>
3776
3777
3778#include <cstring> // strlen
3779#include <string> // string
3780#include <utility> // forward
3781
3782// #include <nlohmann/detail/meta/cpp_future.hpp>
3783
3784// #include <nlohmann/detail/meta/detected.hpp>
3785
3786
3787namespace nlohmann
3788{
3789 namespace detail
3790 {
3791
3792 inline std::size_t concat_length()
3793 {
3794 return 0;
3795 }
3796
3797 template<typename... Args>
3798 inline std::size_t concat_length(const char* cstr, Args&& ... rest);
3799
3800 template<typename StringType, typename... Args>
3801 inline std::size_t concat_length(const StringType& str, Args&& ... rest);
3802
3803 template<typename... Args>
3804 inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
3805 {
3806 return 1 + concat_length(std::forward<Args>(rest)...);
3807 }
3808
3809 template<typename... Args>
3810 inline std::size_t concat_length(const char* cstr, Args&& ... rest)
3811 {
3812 // cppcheck-suppress ignoredReturnValue
3813 return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
3814 }
3815
3816 template<typename StringType, typename... Args>
3817 inline std::size_t concat_length(const StringType& str, Args&& ... rest)
3818 {
3819 return str.size() + concat_length(std::forward<Args>(rest)...);
3820 }
3821
3822 template<typename OutStringType>
3823 inline void concat_into(OutStringType& /*out*/)
3824 {}
3825
3826 template<typename StringType, typename Arg>
3827 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg&& >()));
3828
3829 template<typename StringType, typename Arg>
3831
3832 template<typename StringType, typename Arg>
3833 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg&& >());
3834
3835 template<typename StringType, typename Arg>
3837
3838 template<typename StringType, typename Arg>
3839 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
3840
3841 template<typename StringType, typename Arg>
3843
3844 template<typename StringType, typename Arg>
3845 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
3846
3847 template<typename StringType, typename Arg>
3849
3850 template < typename OutStringType, typename Arg, typename... Args,
3853 inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest);
3854
3855 template < typename OutStringType, typename Arg, typename... Args,
3859 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3860
3861 template < typename OutStringType, typename Arg, typename... Args,
3866 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3867
3868 template<typename OutStringType, typename Arg, typename... Args,
3870 inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest)
3871 {
3872 out.append(std::forward<Arg>(arg));
3873 concat_into(out, std::forward<Args>(rest)...);
3874 }
3875
3876 template < typename OutStringType, typename Arg, typename... Args,
3877 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3878 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
3879 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
3880 {
3881 out += std::forward<Arg>(arg);
3882 concat_into(out, std::forward<Args>(rest)...);
3883 }
3884
3885 template < typename OutStringType, typename Arg, typename... Args,
3886 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3887 && !detect_string_can_append_op<OutStringType, Arg>::value
3888 && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
3889 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
3890 {
3891 out.append(arg.begin(), arg.end());
3892 concat_into(out, std::forward<Args>(rest)...);
3893 }
3894
3895 template < typename OutStringType, typename Arg, typename... Args,
3896 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3897 && !detect_string_can_append_op<OutStringType, Arg>::value
3898 && !detect_string_can_append_iter<OutStringType, Arg>::value
3899 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
3900 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
3901 {
3902 out.append(arg.data(), arg.size());
3903 concat_into(out, std::forward<Args>(rest)...);
3904 }
3905
3906 template<typename OutStringType = std::string, typename... Args>
3907 inline OutStringType concat(Args && ... args)
3908 {
3909 OutStringType str;
3910 str.reserve(concat_length(std::forward<Args>(args)...));
3911 concat_into(str, std::forward<Args>(args)...);
3912 return str;
3913 }
3914
3915 } // namespace detail
3916} // namespace nlohmann
3917
3918
3919
3920namespace nlohmann
3921{
3922 namespace detail
3923 {
3925 // exceptions //
3927
3930 class exception : public std::exception
3931 {
3932 public:
3934 const char* what() const noexcept override
3935 {
3936 return m.what();
3937 }
3938
3940 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
3941
3942 protected:
3944 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
3945
3946 static std::string name(const std::string& ename, int id_)
3947 {
3948 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
3949 }
3950
3951 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
3952 {
3953 return "";
3954 }
3955
3956 template<typename BasicJsonType>
3957 static std::string diagnostics(const BasicJsonType* leaf_element)
3958 {
3959#if JSON_DIAGNOSTICS
3960 std::vector<std::string> tokens;
3961 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
3962 {
3963 switch (current->m_parent->type())
3964 {
3965 case value_t::array:
3966 {
3967 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
3968 {
3969 if (&current->m_parent->m_value.array->operator[](i) == current)
3970 {
3971 tokens.emplace_back(std::to_string(i));
3972 break;
3973 }
3974 }
3975 break;
3976 }
3977
3978 case value_t::object:
3979 {
3980 for (const auto& element : *current->m_parent->m_value.object)
3981 {
3982 if (&element.second == current)
3983 {
3984 tokens.emplace_back(element.first.c_str());
3985 break;
3986 }
3987 }
3988 break;
3989 }
3990
3991 case value_t::null: // LCOV_EXCL_LINE
3992 case value_t::string: // LCOV_EXCL_LINE
3993 case value_t::boolean: // LCOV_EXCL_LINE
3994 case value_t::number_integer: // LCOV_EXCL_LINE
3995 case value_t::number_unsigned: // LCOV_EXCL_LINE
3996 case value_t::number_float: // LCOV_EXCL_LINE
3997 case value_t::binary: // LCOV_EXCL_LINE
3998 case value_t::discarded: // LCOV_EXCL_LINE
3999 default: // LCOV_EXCL_LINE
4000 break; // LCOV_EXCL_LINE
4001 }
4002 }
4003
4004 if (tokens.empty())
4005 {
4006 return "";
4007 }
4008
4009 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4010 [](const std::string& a, const std::string& b)
4011 {
4012 return concat(a, '/', detail::escape(b));
4013 });
4014 return concat('(', str, ") ");
4015#else
4016 static_cast<void>(leaf_element);
4017 return "";
4018#endif
4019 }
4020
4021 private:
4023 std::runtime_error m;
4024 };
4025
4028 class parse_error : public exception
4029 {
4030 public:
4040 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4041 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4042 {
4043 std::string w = concat(exception::name("parse_error", id_), "parse error",
4044 position_string(pos), ": ", exception::diagnostics(context), what_arg);
4045 return { id_, pos.chars_read_total, w.c_str() };
4046 }
4047
4048 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4049 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4050 {
4051 std::string w = concat(exception::name("parse_error", id_), "parse error",
4052 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4053 ": ", exception::diagnostics(context), what_arg);
4054 return { id_, byte_, w.c_str() };
4055 }
4056
4066 const std::size_t byte;
4067
4068 private:
4069 parse_error(int id_, std::size_t byte_, const char* what_arg)
4070 : exception(id_, what_arg), byte(byte_) {}
4071
4072 static std::string position_string(const position_t& pos)
4073 {
4074 return concat(" at line ", std::to_string(pos.lines_read + 1),
4075 ", column ", std::to_string(pos.chars_read_current_line));
4076 }
4077 };
4078
4082 {
4083 public:
4084 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4085 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4086 {
4087 std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4088 return { id_, w.c_str() };
4089 }
4090
4091 private:
4093 invalid_iterator(int id_, const char* what_arg)
4094 : exception(id_, what_arg) {}
4095 };
4096
4099 class type_error : public exception
4100 {
4101 public:
4102 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4103 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4104 {
4105 std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4106 return { id_, w.c_str() };
4107 }
4108
4109 private:
4111 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4112 };
4113
4117 {
4118 public:
4119 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4120 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4121 {
4122 std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4123 return { id_, w.c_str() };
4124 }
4125
4126 private:
4128 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4129 };
4130
4133 class other_error : public exception
4134 {
4135 public:
4136 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4137 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4138 {
4139 std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4140 return { id_, w.c_str() };
4141 }
4142
4143 private:
4145 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4146 };
4147
4148 } // namespace detail
4149} // namespace nlohmann
4150
4151// #include <nlohmann/detail/macro_scope.hpp>
4152
4153// #include <nlohmann/detail/meta/cpp_future.hpp>
4154
4155// #include <nlohmann/detail/meta/identity_tag.hpp>
4156
4157
4158namespace nlohmann
4159{
4160 namespace detail
4161 {
4162 // dispatching helper struct
4163 template <class T> struct identity_tag {};
4164 } // namespace detail
4165} // namespace nlohmann
4166
4167// #include <nlohmann/detail/meta/type_traits.hpp>
4168
4169// #include <nlohmann/detail/string_concat.hpp>
4170
4171// #include <nlohmann/detail/value_t.hpp>
4172
4173
4174#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4175#include <experimental/filesystem>
4176namespace nlohmann::detail
4177{
4178 namespace std_fs = std::experimental::filesystem;
4179} // namespace nlohmann::detail
4180#elif JSON_HAS_FILESYSTEM
4181#include <filesystem>
4182namespace nlohmann::detail
4183{
4184 namespace std_fs = std::filesystem;
4185} // namespace nlohmann::detail
4186#endif
4187
4188namespace nlohmann
4189{
4190 namespace detail
4191 {
4192 template<typename BasicJsonType>
4193 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4194 {
4195 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4196 {
4197 JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4198 }
4199 n = nullptr;
4200 }
4201
4202 // overloads for basic_json template parameters
4203 template < typename BasicJsonType, typename ArithmeticType,
4204 enable_if_t < std::is_arithmetic<ArithmeticType>::value &&
4205 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4206 int > = 0 >
4207 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4208 {
4209 switch (static_cast<value_t>(j))
4210 {
4212 {
4213 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4214 break;
4215 }
4217 {
4218 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4219 break;
4220 }
4222 {
4223 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4224 break;
4225 }
4226
4227 case value_t::null:
4228 case value_t::object:
4229 case value_t::array:
4230 case value_t::string:
4231 case value_t::boolean:
4232 case value_t::binary:
4233 case value_t::discarded:
4234 default:
4235 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4236 }
4237 }
4238
4239 template<typename BasicJsonType>
4240 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4241 {
4242 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4243 {
4244 JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4245 }
4246 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4247 }
4248
4249 template<typename BasicJsonType>
4250 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4251 {
4252 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4253 {
4254 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4255 }
4256 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4257 }
4258
4259 template <
4260 typename BasicJsonType, typename StringType,
4261 enable_if_t <
4262 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4263 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4264 && !is_json_ref<StringType>::value, int > = 0 >
4265 inline void from_json(const BasicJsonType& j, StringType& s)
4266 {
4267 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4268 {
4269 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4270 }
4271
4272 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4273 }
4274
4275 template<typename BasicJsonType>
4276 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4277 {
4278 get_arithmetic_value(j, val);
4279 }
4280
4281 template<typename BasicJsonType>
4282 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4283 {
4284 get_arithmetic_value(j, val);
4285 }
4286
4287 template<typename BasicJsonType>
4288 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4289 {
4290 get_arithmetic_value(j, val);
4291 }
4292
4293 template<typename BasicJsonType, typename EnumType,
4294 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4295 inline void from_json(const BasicJsonType& j, EnumType& e)
4296 {
4297 typename std::underlying_type<EnumType>::type val;
4298 get_arithmetic_value(j, val);
4299 e = static_cast<EnumType>(val);
4300 }
4301
4302 // forward_list doesn't have an insert method
4303 template<typename BasicJsonType, typename T, typename Allocator,
4304 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4305 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4306 {
4307 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4308 {
4309 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4310 }
4311 l.clear();
4312 std::transform(j.rbegin(), j.rend(),
4313 std::front_inserter(l), [](const BasicJsonType& i)
4314 {
4315 return i.template get<T>();
4316 });
4317 }
4318
4319 // valarray doesn't have an insert method
4320 template<typename BasicJsonType, typename T,
4321 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4322 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4323 {
4324 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4325 {
4326 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4327 }
4328 l.resize(j.size());
4329 std::transform(j.begin(), j.end(), std::begin(l),
4330 [](const BasicJsonType& elem)
4331 {
4332 return elem.template get<T>();
4333 });
4334 }
4335
4336 template<typename BasicJsonType, typename T, std::size_t N>
4337 auto from_json(const BasicJsonType& j, T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4338 -> decltype(j.template get<T>(), void())
4339 {
4340 for (std::size_t i = 0; i < N; ++i)
4341 {
4342 arr[i] = j.at(i).template get<T>();
4343 }
4344 }
4345
4346 template<typename BasicJsonType>
4347 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4348 {
4349 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4350 }
4351
4352 template<typename BasicJsonType, typename T, std::size_t N>
4353 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4354 priority_tag<2> /*unused*/)
4355 -> decltype(j.template get<T>(), void())
4356 {
4357 for (std::size_t i = 0; i < N; ++i)
4358 {
4359 arr[i] = j.at(i).template get<T>();
4360 }
4361 }
4362
4363 template<typename BasicJsonType, typename ConstructibleArrayType,
4365 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4366 int> = 0>
4367 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4368 -> decltype(
4369 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4370 j.template get<typename ConstructibleArrayType::value_type>(),
4371 void())
4372 {
4373 using std::end;
4374
4375 ConstructibleArrayType ret;
4376 ret.reserve(j.size());
4377 std::transform(j.begin(), j.end(),
4378 std::inserter(ret, end(ret)), [](const BasicJsonType& i)
4379 {
4380 // get<BasicJsonType>() returns *this, this won't call a from_json
4381 // method when value_type is BasicJsonType
4382 return i.template get<typename ConstructibleArrayType::value_type>();
4383 });
4384 arr = std::move(ret);
4385 }
4386
4387 template<typename BasicJsonType, typename ConstructibleArrayType,
4389 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4390 int> = 0>
4391 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4392 priority_tag<0> /*unused*/)
4393 {
4394 using std::end;
4395
4396 ConstructibleArrayType ret;
4397 std::transform(
4398 j.begin(), j.end(), std::inserter(ret, end(ret)),
4399 [](const BasicJsonType& i)
4400 {
4401 // get<BasicJsonType>() returns *this, this won't call a from_json
4402 // method when value_type is BasicJsonType
4403 return i.template get<typename ConstructibleArrayType::value_type>();
4404 });
4405 arr = std::move(ret);
4406 }
4407
4408 template < typename BasicJsonType, typename ConstructibleArrayType,
4409 enable_if_t <
4410 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value &&
4411 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
4413 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value &&
4414 !is_basic_json<ConstructibleArrayType>::value,
4415 int > = 0 >
4416 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4417 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4418 j.template get<typename ConstructibleArrayType::value_type>(),
4419 void())
4420 {
4421 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4422 {
4423 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4424 }
4425
4426 from_json_array_impl(j, arr, priority_tag<3> {});
4427 }
4428
4429 template < typename BasicJsonType, typename T, std::size_t... Idx >
4430 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4431 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4432 {
4433 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4434 }
4435
4436 template < typename BasicJsonType, typename T, std::size_t N >
4437 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4438 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4439 {
4440 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4441 {
4442 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4443 }
4444
4445 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4446 }
4447
4448 template<typename BasicJsonType>
4449 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4450 {
4451 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4452 {
4453 JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4454 }
4455
4456 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4457 }
4458
4459 template<typename BasicJsonType, typename ConstructibleObjectType,
4460 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4461 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4462 {
4463 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4464 {
4465 JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4466 }
4467
4468 ConstructibleObjectType ret;
4469 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4470 using value_type = typename ConstructibleObjectType::value_type;
4471 std::transform(
4472 inner_object->begin(), inner_object->end(),
4473 std::inserter(ret, ret.begin()),
4474 [](typename BasicJsonType::object_t::value_type const& p)
4475 {
4476 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4477 });
4478 obj = std::move(ret);
4479 }
4480
4481 // overload for arithmetic types, not chosen for basic_json template arguments
4482 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4483 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4484 // an arithmetic type?
4485 template < typename BasicJsonType, typename ArithmeticType,
4486 enable_if_t <
4487 std::is_arithmetic<ArithmeticType>::value &&
4488 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value &&
4489 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
4490 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
4491 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4492 int > = 0 >
4493 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4494 {
4495 switch (static_cast<value_t>(j))
4496 {
4498 {
4499 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4500 break;
4501 }
4503 {
4504 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4505 break;
4506 }
4508 {
4509 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4510 break;
4511 }
4512 case value_t::boolean:
4513 {
4514 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4515 break;
4516 }
4517
4518 case value_t::null:
4519 case value_t::object:
4520 case value_t::array:
4521 case value_t::string:
4522 case value_t::binary:
4523 case value_t::discarded:
4524 default:
4525 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4526 }
4527 }
4528
4529 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4530 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4531 {
4532 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4533 }
4534
4535 template < typename BasicJsonType, class A1, class A2 >
4536 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4537 {
4538 return { std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4539 std::forward<BasicJsonType>(j).at(1).template get<A2>() };
4540 }
4541
4542 template<typename BasicJsonType, typename A1, typename A2>
4543 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4544 {
4545 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4546 }
4547
4548 template<typename BasicJsonType, typename... Args>
4549 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4550 {
4551 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4552 }
4553
4554 template<typename BasicJsonType, typename... Args>
4555 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4556 {
4557 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4558 }
4559
4560 template<typename BasicJsonType, typename TupleRelated>
4561 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4562 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4563 {
4564 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4565 {
4566 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4567 }
4568
4569 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4570 }
4571
4572 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4573 typename = enable_if_t < !std::is_constructible <
4574 typename BasicJsonType::string_t, Key >::value >>
4575 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4576 {
4577 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4578 {
4579 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4580 }
4581 m.clear();
4582 for (const auto& p : j)
4583 {
4584 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4585 {
4586 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4587 }
4588 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4589 }
4590 }
4591
4592 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4593 typename = enable_if_t < !std::is_constructible <
4594 typename BasicJsonType::string_t, Key >::value >>
4595 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4596 {
4597 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4598 {
4599 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4600 }
4601 m.clear();
4602 for (const auto& p : j)
4603 {
4604 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4605 {
4606 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4607 }
4608 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4609 }
4610 }
4611
4612#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4613 template<typename BasicJsonType>
4614 inline void from_json(const BasicJsonType& j, std_fs::path& p)
4615 {
4616 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4617 {
4618 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4619 }
4620 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4621 }
4622#endif
4623
4625 {
4626 template<typename BasicJsonType, typename T>
4627 auto operator()(const BasicJsonType& j, T&& val) const
4628 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4629 -> decltype(from_json(j, std::forward<T>(val)))
4630 {
4631 return from_json(j, std::forward<T>(val));
4632 }
4633 };
4634 } // namespace detail
4635
4636#ifndef JSON_HAS_CPP_17
4640 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4641 {
4642#endif
4643 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
4645#ifndef JSON_HAS_CPP_17
4646 } // namespace
4647#endif
4648} // namespace nlohmann
4649
4650// #include <nlohmann/detail/conversions/to_json.hpp>
4651
4652
4653#include <algorithm> // copy
4654#include <iterator> // begin, end
4655#include <string> // string
4656#include <tuple> // tuple, get
4657#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4658#include <utility> // move, forward, declval, pair
4659#include <valarray> // valarray
4660#include <vector> // vector
4661
4662// #include <nlohmann/detail/macro_scope.hpp>
4663
4664// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4665
4666
4667#include <cstddef> // size_t
4668#include <iterator> // input_iterator_tag
4669#include <string> // string, to_string
4670#include <tuple> // tuple_size, get, tuple_element
4671#include <utility> // move
4672
4673#if JSON_HAS_RANGES
4674#include <ranges> // enable_borrowed_range
4675#endif
4676
4677// #include <nlohmann/detail/meta/type_traits.hpp>
4678
4679// #include <nlohmann/detail/value_t.hpp>
4680
4681
4682namespace nlohmann
4683{
4684 namespace detail
4685 {
4686 template<typename string_type>
4687 void int_to_string(string_type& target, std::size_t value)
4688 {
4689 // For ADL
4690 using std::to_string;
4691 target = to_string(value);
4692 }
4693 template<typename IteratorType> class iteration_proxy_value
4694 {
4695 public:
4696 using difference_type = std::ptrdiff_t;
4700 using iterator_category = std::input_iterator_tag;
4701 using string_type = typename std::remove_cv< typename std::remove_reference<decltype(std::declval<IteratorType>().key()) >::type >::type;
4702
4703 private:
4705 IteratorType anchor{};
4707 std::size_t array_index = 0;
4709 mutable std::size_t array_index_last = 0;
4711 mutable string_type array_index_str = "0";
4713 string_type empty_str{};
4714
4715 public:
4716 explicit iteration_proxy_value() = default;
4717 explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
4718 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
4719 && std::is_nothrow_default_constructible<string_type>::value)
4720 : anchor(std::move(it))
4721 , array_index(array_index_)
4722 {}
4723
4726 // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
4728 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
4729 && std::is_nothrow_move_constructible<string_type>::value) = default;
4731 noexcept(std::is_nothrow_move_assignable<IteratorType>::value
4732 && std::is_nothrow_move_assignable<string_type>::value) = default;
4734
4736 const iteration_proxy_value& operator*() const
4737 {
4738 return *this;
4739 }
4740
4743 {
4744 ++anchor;
4745 ++array_index;
4746
4747 return *this;
4748 }
4749
4750 iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
4751 {
4752 auto tmp = iteration_proxy_value(anchor, array_index);
4753 ++anchor;
4754 ++array_index;
4755 return tmp;
4756 }
4757
4760 {
4761 return anchor == o.anchor;
4762 }
4763
4766 {
4767 return anchor != o.anchor;
4768 }
4769
4771 const string_type& key() const
4772 {
4773 JSON_ASSERT(anchor.m_object != nullptr);
4774
4775 switch (anchor.m_object->type())
4776 {
4777 // use integer array index as key
4778 case value_t::array:
4779 {
4780 if (array_index != array_index_last)
4781 {
4782 int_to_string(array_index_str, array_index);
4783 array_index_last = array_index;
4784 }
4785 return array_index_str;
4786 }
4787
4788 // use key from the object
4789 case value_t::object:
4790 return anchor.key();
4791
4792 // use an empty key for all primitive types
4793 case value_t::null:
4794 case value_t::string:
4795 case value_t::boolean:
4799 case value_t::binary:
4800 case value_t::discarded:
4801 default:
4802 return empty_str;
4803 }
4804 }
4805
4807 typename IteratorType::reference value() const
4808 {
4809 return anchor.value();
4810 }
4811 };
4812
4814 template<typename IteratorType> class iteration_proxy
4815 {
4816 private:
4818 typename IteratorType::pointer container = nullptr;
4819
4820 public:
4821 explicit iteration_proxy() = default;
4822
4824 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4825 : container(&cont) {}
4826
4829 iteration_proxy(iteration_proxy&&) noexcept = default;
4830 iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
4831 ~iteration_proxy() = default;
4832
4834 iteration_proxy_value<IteratorType> begin() const noexcept
4835 {
4836 return iteration_proxy_value<IteratorType>(container->begin());
4837 }
4838
4841 {
4842 return iteration_proxy_value<IteratorType>(container->end());
4843 }
4844 };
4845
4846 // Structured Bindings Support
4847 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4848 // And see https://github.com/nlohmann/json/pull/1391
4849 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4851 {
4852 return i.key();
4853 }
4854 // Structured Bindings Support
4855 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4856 // And see https://github.com/nlohmann/json/pull/1391
4857 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4858 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4859 {
4860 return i.value();
4861 }
4862 } // namespace detail
4863} // namespace nlohmann
4864
4865// The Addition to the STD Namespace is required to add
4866// Structured Bindings Support to the iteration_proxy_value class
4867// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4868// And see https://github.com/nlohmann/json/pull/1391
4869namespace std
4870{
4871#if defined(__clang__)
4872 // Fix: https://github.com/nlohmann/json/issues/1401
4873#pragma clang diagnostic push
4874#pragma clang diagnostic ignored "-Wmismatched-tags"
4875#endif
4876 template<typename IteratorType>
4877 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4878 : public std::integral_constant<std::size_t, 2> {};
4879
4880 template<std::size_t N, typename IteratorType>
4881 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4882 {
4883 public:
4884 using type = decltype(
4885 get<N>(std::declval <
4887 };
4888#if defined(__clang__)
4889#pragma clang diagnostic pop
4890#endif
4891} // namespace std
4892
4893#if JSON_HAS_RANGES
4894template <typename IteratorType>
4895inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
4896#endif
4897
4898// #include <nlohmann/detail/meta/cpp_future.hpp>
4899
4900// #include <nlohmann/detail/meta/type_traits.hpp>
4901
4902// #include <nlohmann/detail/value_t.hpp>
4903
4904
4905#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4906#include <experimental/filesystem>
4907namespace nlohmann::detail
4908{
4909 namespace std_fs = std::experimental::filesystem;
4910} // namespace nlohmann::detail
4911#elif JSON_HAS_FILESYSTEM
4912#include <filesystem>
4913namespace nlohmann::detail
4914{
4915 namespace std_fs = std::filesystem;
4916} // namespace nlohmann::detail
4917#endif
4918
4919namespace nlohmann
4920{
4921 namespace detail
4922 {
4924 // constructors //
4926
4927 /*
4928 * Note all external_constructor<>::construct functions need to call
4929 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4930 * allocated value (e.g., a string). See bug issue
4931 * https://github.com/nlohmann/json/issues/2865 for more information.
4932 */
4933
4934 template<value_t> struct external_constructor;
4935
4936 template<>
4938 {
4939 template<typename BasicJsonType>
4940 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4941 {
4942 j.m_value.destroy(j.m_type);
4943 j.m_type = value_t::boolean;
4944 j.m_value = b;
4945 j.assert_invariant();
4946 }
4947 };
4948
4949 template<>
4951 {
4952 template<typename BasicJsonType>
4953 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4954 {
4955 j.m_value.destroy(j.m_type);
4956 j.m_type = value_t::string;
4957 j.m_value = s;
4958 j.assert_invariant();
4959 }
4960
4961 template<typename BasicJsonType>
4962 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4963 {
4964 j.m_value.destroy(j.m_type);
4965 j.m_type = value_t::string;
4966 j.m_value = std::move(s);
4967 j.assert_invariant();
4968 }
4969
4970 template < typename BasicJsonType, typename CompatibleStringType,
4972 int > = 0 >
4973 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4974 {
4975 j.m_value.destroy(j.m_type);
4976 j.m_type = value_t::string;
4977 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4978 j.assert_invariant();
4979 }
4980 };
4981
4982 template<>
4984 {
4985 template<typename BasicJsonType>
4986 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4987 {
4988 j.m_value.destroy(j.m_type);
4989 j.m_type = value_t::binary;
4990 j.m_value = typename BasicJsonType::binary_t(b);
4991 j.assert_invariant();
4992 }
4993
4994 template<typename BasicJsonType>
4995 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4996 {
4997 j.m_value.destroy(j.m_type);
4998 j.m_type = value_t::binary;
4999 j.m_value = typename BasicJsonType::binary_t(std::move(b));
5000 j.assert_invariant();
5001 }
5002 };
5003
5004 template<>
5006 {
5007 template<typename BasicJsonType>
5008 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5009 {
5010 j.m_value.destroy(j.m_type);
5011 j.m_type = value_t::number_float;
5012 j.m_value = val;
5013 j.assert_invariant();
5014 }
5015 };
5016
5017 template<>
5019 {
5020 template<typename BasicJsonType>
5021 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5022 {
5023 j.m_value.destroy(j.m_type);
5024 j.m_type = value_t::number_unsigned;
5025 j.m_value = val;
5026 j.assert_invariant();
5027 }
5028 };
5029
5030 template<>
5032 {
5033 template<typename BasicJsonType>
5034 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5035 {
5036 j.m_value.destroy(j.m_type);
5037 j.m_type = value_t::number_integer;
5038 j.m_value = val;
5039 j.assert_invariant();
5040 }
5041 };
5042
5043 template<>
5045 {
5046 template<typename BasicJsonType>
5047 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5048 {
5049 j.m_value.destroy(j.m_type);
5050 j.m_type = value_t::array;
5051 j.m_value = arr;
5052 j.set_parents();
5053 j.assert_invariant();
5054 }
5055
5056 template<typename BasicJsonType>
5057 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5058 {
5059 j.m_value.destroy(j.m_type);
5060 j.m_type = value_t::array;
5061 j.m_value = std::move(arr);
5062 j.set_parents();
5063 j.assert_invariant();
5064 }
5065
5066 template < typename BasicJsonType, typename CompatibleArrayType,
5068 int > = 0 >
5069 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5070 {
5071 using std::begin;
5072 using std::end;
5073
5074 j.m_value.destroy(j.m_type);
5075 j.m_type = value_t::array;
5076 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5077 j.set_parents();
5078 j.assert_invariant();
5079 }
5080
5081 template<typename BasicJsonType>
5082 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5083 {
5084 j.m_value.destroy(j.m_type);
5085 j.m_type = value_t::array;
5086 j.m_value = value_t::array;
5087 j.m_value.array->reserve(arr.size());
5088 for (const bool x : arr)
5089 {
5090 j.m_value.array->push_back(x);
5091 j.set_parent(j.m_value.array->back());
5092 }
5093 j.assert_invariant();
5094 }
5095
5096 template<typename BasicJsonType, typename T,
5098 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5099 {
5100 j.m_value.destroy(j.m_type);
5101 j.m_type = value_t::array;
5102 j.m_value = value_t::array;
5103 j.m_value.array->resize(arr.size());
5104 if (arr.size() > 0)
5105 {
5106 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
5107 }
5108 j.set_parents();
5109 j.assert_invariant();
5110 }
5111 };
5112
5113 template<>
5115 {
5116 template<typename BasicJsonType>
5117 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5118 {
5119 j.m_value.destroy(j.m_type);
5120 j.m_type = value_t::object;
5121 j.m_value = obj;
5122 j.set_parents();
5123 j.assert_invariant();
5124 }
5125
5126 template<typename BasicJsonType>
5127 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5128 {
5129 j.m_value.destroy(j.m_type);
5130 j.m_type = value_t::object;
5131 j.m_value = std::move(obj);
5132 j.set_parents();
5133 j.assert_invariant();
5134 }
5135
5136 template < typename BasicJsonType, typename CompatibleObjectType,
5138 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5139 {
5140 using std::begin;
5141 using std::end;
5142
5143 j.m_value.destroy(j.m_type);
5144 j.m_type = value_t::object;
5145 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5146 j.set_parents();
5147 j.assert_invariant();
5148 }
5149 };
5150
5152 // to_json //
5154
5155 template<typename BasicJsonType, typename T,
5156 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5157 inline void to_json(BasicJsonType& j, T b) noexcept
5158 {
5160 }
5161
5162 template<typename BasicJsonType, typename CompatibleString,
5163 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5164 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5165 {
5167 }
5168
5169 template<typename BasicJsonType>
5170 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5171 {
5173 }
5174
5175 template<typename BasicJsonType, typename FloatType,
5176 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5177 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5178 {
5179 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5180 }
5181
5182 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5183 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5184 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5185 {
5186 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5187 }
5188
5189 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5190 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5191 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5192 {
5193 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5194 }
5195
5196 template<typename BasicJsonType, typename EnumType,
5197 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5198 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5199 {
5200 using underlying_type = typename std::underlying_type<EnumType>::type;
5201 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5202 }
5203
5204 template<typename BasicJsonType>
5205 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5206 {
5208 }
5209
5210 template < typename BasicJsonType, typename CompatibleArrayType,
5211 enable_if_t < is_compatible_array_type<BasicJsonType,
5212 CompatibleArrayType>::value &&
5213 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value &&
5215 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value &&
5216 !is_basic_json<CompatibleArrayType>::value,
5217 int > = 0 >
5218 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5219 {
5221 }
5222
5223 template<typename BasicJsonType>
5224 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5225 {
5227 }
5228
5229 template<typename BasicJsonType, typename T,
5230 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5231 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5232 {
5234 }
5235
5236 template<typename BasicJsonType>
5237 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5238 {
5240 }
5241
5242 template < typename BasicJsonType, typename CompatibleObjectType,
5243 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5244 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5245 {
5247 }
5248
5249 template<typename BasicJsonType>
5250 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5251 {
5253 }
5254
5255 template <
5256 typename BasicJsonType, typename T, std::size_t N,
5257 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5258 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5259 int > = 0 >
5260 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5261 {
5263 }
5264
5265 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5266 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5267 {
5268 j = { p.first, p.second };
5269 }
5270
5271 // for https://github.com/nlohmann/json/pull/1134
5272 template<typename BasicJsonType, typename T,
5273 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5274 inline void to_json(BasicJsonType& j, const T& b)
5275 {
5276 j = { {b.key(), b.value()} };
5277 }
5278
5279 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5280 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5281 {
5282 j = { std::get<Idx>(t)... };
5283 }
5284
5285 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5286 inline void to_json(BasicJsonType& j, const T& t)
5287 {
5288 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5289 }
5290
5291#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5292 template<typename BasicJsonType>
5293 inline void to_json(BasicJsonType& j, const std_fs::path& p)
5294 {
5295 j = p.string();
5296 }
5297#endif
5298
5300 {
5301 template<typename BasicJsonType, typename T>
5302 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5303 -> decltype(to_json(j, std::forward<T>(val)), void())
5304 {
5305 return to_json(j, std::forward<T>(val));
5306 }
5307 };
5308 } // namespace detail
5309
5310#ifndef JSON_HAS_CPP_17
5314 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5315 {
5316#endif
5317 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5319#ifndef JSON_HAS_CPP_17
5320 } // namespace
5321#endif
5322} // namespace nlohmann
5323
5324// #include <nlohmann/detail/meta/identity_tag.hpp>
5325
5326// #include <nlohmann/detail/meta/type_traits.hpp>
5327
5328
5329namespace nlohmann
5330{
5331
5333 template<typename ValueType, typename>
5335 {
5338 template<typename BasicJsonType, typename TargetType = ValueType>
5339 static auto from_json(BasicJsonType&& j, TargetType& val) noexcept(
5340 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5341 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5342 {
5343 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5344 }
5345
5348 template<typename BasicJsonType, typename TargetType = ValueType>
5349 static auto from_json(BasicJsonType&& j) noexcept(
5350 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5351 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5352 {
5353 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5354 }
5355
5358 template<typename BasicJsonType, typename TargetType = ValueType>
5359 static auto to_json(BasicJsonType& j, TargetType&& val) noexcept(
5360 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5361 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5362 {
5363 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5364 }
5365 };
5366} // namespace nlohmann
5367
5368// #include <nlohmann/byte_container_with_subtype.hpp>
5369
5370
5371#include <cstdint> // uint8_t, uint64_t
5372#include <tuple> // tie
5373#include <utility> // move
5374
5375namespace nlohmann
5376{
5377
5380 template<typename BinaryType>
5381 class byte_container_with_subtype : public BinaryType
5382 {
5383 public:
5384 using container_type = BinaryType;
5385 using subtype_type = std::uint64_t;
5386
5389 : container_type()
5390 {}
5391
5394 : container_type(b)
5395 {}
5396
5398 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5399 : container_type(std::move(b))
5400 {}
5401
5404 : container_type(b)
5405 , m_subtype(subtype_)
5406 , m_has_subtype(true)
5407 {}
5408
5410 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5411 : container_type(std::move(b))
5412 , m_subtype(subtype_)
5413 , m_has_subtype(true)
5414 {}
5415
5417 {
5418 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5419 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5420 }
5421
5423 {
5424 return !(rhs == *this);
5425 }
5426
5429 void set_subtype(subtype_type subtype_) noexcept
5430 {
5431 m_subtype = subtype_;
5432 m_has_subtype = true;
5433 }
5434
5437 constexpr subtype_type subtype() const noexcept
5438 {
5439 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5440 }
5441
5444 constexpr bool has_subtype() const noexcept
5445 {
5446 return m_has_subtype;
5447 }
5448
5451 void clear_subtype() noexcept
5452 {
5453 m_subtype = 0;
5454 m_has_subtype = false;
5455 }
5456
5457 private:
5458 subtype_type m_subtype = 0;
5459 bool m_has_subtype = false;
5460 };
5461
5462} // namespace nlohmann
5463
5464// #include <nlohmann/detail/conversions/from_json.hpp>
5465
5466// #include <nlohmann/detail/conversions/to_json.hpp>
5467
5468// #include <nlohmann/detail/exceptions.hpp>
5469
5470// #include <nlohmann/detail/hash.hpp>
5471
5472
5473#include <cstdint> // uint8_t
5474#include <cstddef> // size_t
5475#include <functional> // hash
5476
5477// #include <nlohmann/detail/macro_scope.hpp>
5478
5479// #include <nlohmann/detail/value_t.hpp>
5480
5481
5482namespace nlohmann
5483{
5484 namespace detail
5485 {
5486
5487 // boost::hash_combine
5488 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5489 {
5490 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5491 return seed;
5492 }
5493
5505 template<typename BasicJsonType>
5506 std::size_t hash(const BasicJsonType& j)
5507 {
5508 using string_t = typename BasicJsonType::string_t;
5509 using number_integer_t = typename BasicJsonType::number_integer_t;
5510 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5511 using number_float_t = typename BasicJsonType::number_float_t;
5512
5513 const auto type = static_cast<std::size_t>(j.type());
5514 switch (j.type())
5515 {
5516 case BasicJsonType::value_t::null:
5517 case BasicJsonType::value_t::discarded:
5518 {
5519 return combine(type, 0);
5520 }
5521
5522 case BasicJsonType::value_t::object:
5523 {
5524 auto seed = combine(type, j.size());
5525 for (const auto& element : j.items())
5526 {
5527 const auto h = std::hash<string_t>{}(element.key());
5528 seed = combine(seed, h);
5529 seed = combine(seed, hash(element.value()));
5530 }
5531 return seed;
5532 }
5533
5534 case BasicJsonType::value_t::array:
5535 {
5536 auto seed = combine(type, j.size());
5537 for (const auto& element : j)
5538 {
5539 seed = combine(seed, hash(element));
5540 }
5541 return seed;
5542 }
5543
5544 case BasicJsonType::value_t::string:
5545 {
5546 const auto h = std::hash<string_t>{}(j.template get_ref<const string_t&>());
5547 return combine(type, h);
5548 }
5549
5550 case BasicJsonType::value_t::boolean:
5551 {
5552 const auto h = std::hash<bool>{}(j.template get<bool>());
5553 return combine(type, h);
5554 }
5555
5556 case BasicJsonType::value_t::number_integer:
5557 {
5558 const auto h = std::hash<number_integer_t>{}(j.template get<number_integer_t>());
5559 return combine(type, h);
5560 }
5561
5562 case BasicJsonType::value_t::number_unsigned:
5563 {
5564 const auto h = std::hash<number_unsigned_t>{}(j.template get<number_unsigned_t>());
5565 return combine(type, h);
5566 }
5567
5568 case BasicJsonType::value_t::number_float:
5569 {
5570 const auto h = std::hash<number_float_t>{}(j.template get<number_float_t>());
5571 return combine(type, h);
5572 }
5573
5574 case BasicJsonType::value_t::binary:
5575 {
5576 auto seed = combine(type, j.get_binary().size());
5577 const auto h = std::hash<bool>{}(j.get_binary().has_subtype());
5578 seed = combine(seed, h);
5579 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5580 for (const auto byte : j.get_binary())
5581 {
5582 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5583 }
5584 return seed;
5585 }
5586
5587 default: // LCOV_EXCL_LINE
5588 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5589 return 0; // LCOV_EXCL_LINE
5590 }
5591 }
5592
5593 } // namespace detail
5594} // namespace nlohmann
5595
5596// #include <nlohmann/detail/input/binary_reader.hpp>
5597
5598
5599#include <algorithm> // generate_n
5600#include <array> // array
5601#include <cmath> // ldexp
5602#include <cstddef> // size_t
5603#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5604#include <cstdio> // snprintf
5605#include <cstring> // memcpy
5606#include <iterator> // back_inserter
5607#include <limits> // numeric_limits
5608#include <string> // char_traits, string
5609#include <utility> // make_pair, move
5610#include <vector> // vector
5611#include <map> // map
5612
5613// #include <nlohmann/detail/exceptions.hpp>
5614
5615// #include <nlohmann/detail/input/input_adapters.hpp>
5616
5617
5618#include <array> // array
5619#include <cstddef> // size_t
5620#include <cstring> // strlen
5621#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5622#include <memory> // shared_ptr, make_shared, addressof
5623#include <numeric> // accumulate
5624#include <string> // string, char_traits
5625#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5626#include <utility> // pair, declval
5627
5628#ifndef JSON_NO_IO
5629#include <cstdio> // FILE *
5630#include <istream> // istream
5631#endif // JSON_NO_IO
5632
5633// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5634
5635// #include <nlohmann/detail/macro_scope.hpp>
5636
5637
5638namespace nlohmann
5639{
5640 namespace detail
5641 {
5644
5646 // input adapters //
5648
5649#ifndef JSON_NO_IO
5655 {
5656 public:
5657 using char_type = char;
5658
5660 explicit file_input_adapter(std::FILE* f) noexcept
5661 : m_file(f)
5662 {}
5663
5664 // make class move-only
5667 file_input_adapter& operator=(const file_input_adapter&) = delete;
5670
5671 std::char_traits<char>::int_type get_character() noexcept
5672 {
5673 return std::fgetc(m_file);
5674 }
5675
5676 private:
5678 std::FILE* m_file;
5679 };
5680
5681
5692 {
5693 public:
5694 using char_type = char;
5695
5697 {
5698 // clear stream flags; we use underlying streambuf I/O, do not
5699 // maintain ifstream flags, except eof
5700 if (is != nullptr)
5701 {
5702 is->clear(is->rdstate() & std::ios::eofbit);
5703 }
5704 }
5705
5706 explicit input_stream_adapter(std::istream& i)
5707 : is(&i), sb(i.rdbuf())
5708 {}
5709
5710 // delete because of pointer members
5714
5716 : is(rhs.is), sb(rhs.sb)
5717 {
5718 rhs.is = nullptr;
5719 rhs.sb = nullptr;
5720 }
5721
5722 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5723 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5724 // end up as the same value, e.g. 0xFFFFFFFF.
5725 std::char_traits<char>::int_type get_character()
5726 {
5727 auto res = sb->sbumpc();
5728 // set eof manually, as we don't use the istream interface.
5729 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5730 {
5731 is->clear(is->rdstate() | std::ios::eofbit);
5732 }
5733 return res;
5734 }
5735
5736 private:
5738 std::istream* is = nullptr;
5739 std::streambuf* sb = nullptr;
5740 };
5741#endif // JSON_NO_IO
5742
5743 // General-purpose iterator-based adapter. It might not be as fast as
5744 // theoretically possible for some containers, but it is extremely versatile.
5745 template<typename IteratorType>
5747 {
5748 public:
5749 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5750
5751 iterator_input_adapter(IteratorType first, IteratorType last)
5752 : current(std::move(first)), end(std::move(last))
5753 {}
5754
5755 typename std::char_traits<char_type>::int_type get_character()
5756 {
5757 if (JSON_HEDLEY_LIKELY(current != end))
5758 {
5759 auto result = std::char_traits<char_type>::to_int_type(*current);
5760 std::advance(current, 1);
5761 return result;
5762 }
5763
5764 return std::char_traits<char_type>::eof();
5765 }
5766
5767 private:
5768 IteratorType current;
5769 IteratorType end;
5770
5771 template<typename BaseInputAdapter, size_t T>
5773
5774 bool empty() const
5775 {
5776 return current == end;
5777 }
5778 };
5779
5780
5781 template<typename BaseInputAdapter, size_t T>
5783
5784 template<typename BaseInputAdapter>
5785 struct wide_string_input_helper<BaseInputAdapter, 4>
5786 {
5787 // UTF-32
5788 static void fill_buffer(BaseInputAdapter& input,
5789 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5790 size_t& utf8_bytes_index,
5791 size_t& utf8_bytes_filled)
5792 {
5793 utf8_bytes_index = 0;
5794
5795 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5796 {
5797 utf8_bytes[0] = std::char_traits<char>::eof();
5798 utf8_bytes_filled = 1;
5799 }
5800 else
5801 {
5802 // get the current character
5803 const auto wc = input.get_character();
5804
5805 // UTF-32 to UTF-8 encoding
5806 if (wc < 0x80)
5807 {
5808 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5809 utf8_bytes_filled = 1;
5810 }
5811 else if (wc <= 0x7FF)
5812 {
5813 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5814 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5815 utf8_bytes_filled = 2;
5816 }
5817 else if (wc <= 0xFFFF)
5818 {
5819 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5820 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5821 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5822 utf8_bytes_filled = 3;
5823 }
5824 else if (wc <= 0x10FFFF)
5825 {
5826 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5827 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5828 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5829 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5830 utf8_bytes_filled = 4;
5831 }
5832 else
5833 {
5834 // unknown character
5835 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5836 utf8_bytes_filled = 1;
5837 }
5838 }
5839 }
5840 };
5841
5842 template<typename BaseInputAdapter>
5843 struct wide_string_input_helper<BaseInputAdapter, 2>
5844 {
5845 // UTF-16
5846 static void fill_buffer(BaseInputAdapter& input,
5847 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5848 size_t& utf8_bytes_index,
5849 size_t& utf8_bytes_filled)
5850 {
5851 utf8_bytes_index = 0;
5852
5853 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5854 {
5855 utf8_bytes[0] = std::char_traits<char>::eof();
5856 utf8_bytes_filled = 1;
5857 }
5858 else
5859 {
5860 // get the current character
5861 const auto wc = input.get_character();
5862
5863 // UTF-16 to UTF-8 encoding
5864 if (wc < 0x80)
5865 {
5866 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5867 utf8_bytes_filled = 1;
5868 }
5869 else if (wc <= 0x7FF)
5870 {
5871 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5872 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5873 utf8_bytes_filled = 2;
5874 }
5875 else if (0xD800 > wc || wc >= 0xE000)
5876 {
5877 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5878 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5879 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5880 utf8_bytes_filled = 3;
5881 }
5882 else
5883 {
5884 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5885 {
5886 const auto wc2 = static_cast<unsigned int>(input.get_character());
5887 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5888 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5889 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5890 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5891 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5892 utf8_bytes_filled = 4;
5893 }
5894 else
5895 {
5896 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5897 utf8_bytes_filled = 1;
5898 }
5899 }
5900 }
5901 }
5902 };
5903
5904 // Wraps another input apdater to convert wide character types into individual bytes.
5905 template<typename BaseInputAdapter, typename WideCharType>
5907 {
5908 public:
5909 using char_type = char;
5910
5911 wide_string_input_adapter(BaseInputAdapter base)
5912 : base_adapter(base) {}
5913
5914 typename std::char_traits<char>::int_type get_character() noexcept
5915 {
5916 // check if buffer needs to be filled
5917 if (utf8_bytes_index == utf8_bytes_filled)
5918 {
5919 fill_buffer<sizeof(WideCharType)>();
5920
5921 JSON_ASSERT(utf8_bytes_filled > 0);
5922 JSON_ASSERT(utf8_bytes_index == 0);
5923 }
5924
5925 // use buffer
5926 JSON_ASSERT(utf8_bytes_filled > 0);
5927 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5928 return utf8_bytes[utf8_bytes_index++];
5929 }
5930
5931 private:
5932 BaseInputAdapter base_adapter;
5933
5934 template<size_t T>
5935 void fill_buffer()
5936 {
5937 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5938 }
5939
5941 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = { {0, 0, 0, 0} };
5942
5944 std::size_t utf8_bytes_index = 0;
5946 std::size_t utf8_bytes_filled = 0;
5947 };
5948
5949
5950 template<typename IteratorType, typename Enable = void>
5952 {
5953 using iterator_type = IteratorType;
5954 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5956
5957 static adapter_type create(IteratorType first, IteratorType last)
5958 {
5959 return adapter_type(std::move(first), std::move(last));
5960 }
5961 };
5962
5963 template<typename T>
5965 {
5966 using value_type = typename std::iterator_traits<T>::value_type;
5967 enum
5968 {
5969 value = sizeof(value_type) > 1
5970 };
5971 };
5972
5973 template<typename IteratorType>
5975 {
5976 using iterator_type = IteratorType;
5977 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5980
5981 static adapter_type create(IteratorType first, IteratorType last)
5982 {
5983 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5984 }
5985 };
5986
5987 // General purpose iterator-based input
5988 template<typename IteratorType>
5990 {
5992 return factory_type::create(first, last);
5993 }
5994
5995 // Convenience shorthand from container to iterator
5996 // Enables ADL on begin(container) and end(container)
5997 // Encloses the using declarations in namespace for not to leak them to outside scope
5998
5999 namespace container_input_adapter_factory_impl
6000 {
6001
6002 using std::begin;
6003 using std::end;
6004
6005 template<typename ContainerType, typename Enable = void>
6007
6008 template<typename ContainerType>
6009 struct container_input_adapter_factory< ContainerType,
6010 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6011 {
6012 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6013
6014 static adapter_type create(const ContainerType& container)
6015 {
6016 return input_adapter(begin(container), end(container));
6017 }
6018 };
6019
6020 } // namespace container_input_adapter_factory_impl
6021
6022 template<typename ContainerType>
6024 {
6026 }
6027
6028#ifndef JSON_NO_IO
6029 // Special cases with fast paths
6030 inline file_input_adapter input_adapter(std::FILE* file)
6031 {
6032 return file_input_adapter(file);
6033 }
6034
6035 inline input_stream_adapter input_adapter(std::istream& stream)
6036 {
6037 return input_stream_adapter(stream);
6038 }
6039
6040 inline input_stream_adapter input_adapter(std::istream&& stream)
6041 {
6042 return input_stream_adapter(stream);
6043 }
6044#endif // JSON_NO_IO
6045
6046 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6047
6048 // Null-delimited strings, and the like.
6049 template < typename CharT,
6050 typename std::enable_if <
6051 std::is_pointer<CharT>::value &&
6052 !std::is_array<CharT>::value&&
6053 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6054 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6055 int >::type = 0 >
6057 {
6058 auto length = std::strlen(reinterpret_cast<const char*>(b));
6059 const auto* ptr = reinterpret_cast<const char*>(b);
6060 return input_adapter(ptr, ptr + length);
6061 }
6062
6063 template<typename T, std::size_t N>
6064 auto input_adapter(T(&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6065 {
6066 return input_adapter(array, array + N);
6067 }
6068
6069 // This class only handles inputs of input_buffer_adapter type.
6070 // It's required so that expressions like {ptr, len} can be implicitly cast
6071 // to the correct adapter.
6073 {
6074 public:
6075 template < typename CharT,
6076 typename std::enable_if <
6077 std::is_pointer<CharT>::value&&
6078 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6079 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6080 int >::type = 0 >
6081 span_input_adapter(CharT b, std::size_t l)
6082 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6083
6084 template<class IteratorType,
6085 typename std::enable_if<
6086 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6087 int>::type = 0>
6088 span_input_adapter(IteratorType first, IteratorType last)
6089 : ia(input_adapter(first, last)) {}
6090
6092 {
6093 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6094 }
6095
6096 private:
6098 };
6099 } // namespace detail
6100} // namespace nlohmann
6101
6102// #include <nlohmann/detail/input/json_sax.hpp>
6103
6104
6105#include <cstddef>
6106#include <string> // string
6107#include <utility> // move
6108#include <vector> // vector
6109
6110// #include <nlohmann/detail/exceptions.hpp>
6111
6112// #include <nlohmann/detail/macro_scope.hpp>
6113
6114// #include <nlohmann/detail/string_concat.hpp>
6115
6116
6117namespace nlohmann
6118{
6119
6128 template<typename BasicJsonType>
6130 {
6131 using number_integer_t = typename BasicJsonType::number_integer_t;
6132 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6133 using number_float_t = typename BasicJsonType::number_float_t;
6134 using string_t = typename BasicJsonType::string_t;
6135 using binary_t = typename BasicJsonType::binary_t;
6136
6141 virtual bool null() = 0;
6142
6148 virtual bool boolean(bool val) = 0;
6149
6155 virtual bool number_integer(number_integer_t val) = 0;
6156
6162 virtual bool number_unsigned(number_unsigned_t val) = 0;
6163
6170 virtual bool number_float(number_float_t val, const string_t& s) = 0;
6171
6178 virtual bool string(string_t& val) = 0;
6179
6186 virtual bool binary(binary_t& val) = 0;
6187
6194 virtual bool start_object(std::size_t elements) = 0;
6195
6202 virtual bool key(string_t& val) = 0;
6203
6208 virtual bool end_object() = 0;
6209
6216 virtual bool start_array(std::size_t elements) = 0;
6217
6222 virtual bool end_array() = 0;
6223
6231 virtual bool parse_error(std::size_t position,
6232 const std::string& last_token,
6233 const detail::exception& ex) = 0;
6234
6235 json_sax() = default;
6236 json_sax(const json_sax&) = default;
6237 json_sax(json_sax&&) noexcept = default;
6238 json_sax& operator=(const json_sax&) = default;
6239 json_sax& operator=(json_sax&&) noexcept = default;
6240 virtual ~json_sax() = default;
6241 };
6242
6243
6244 namespace detail
6245 {
6259 template<typename BasicJsonType>
6261 {
6262 public:
6263 using number_integer_t = typename BasicJsonType::number_integer_t;
6264 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6265 using number_float_t = typename BasicJsonType::number_float_t;
6266 using string_t = typename BasicJsonType::string_t;
6267 using binary_t = typename BasicJsonType::binary_t;
6268
6274 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6275 : root(r), allow_exceptions(allow_exceptions_)
6276 {}
6277
6278 // make class move-only
6280 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6282 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6284
6285 bool null()
6286 {
6287 handle_value(nullptr);
6288 return true;
6289 }
6290
6291 bool boolean(bool val)
6292 {
6293 handle_value(val);
6294 return true;
6295 }
6296
6298 {
6299 handle_value(val);
6300 return true;
6301 }
6302
6304 {
6305 handle_value(val);
6306 return true;
6307 }
6308
6309 bool number_float(number_float_t val, const string_t& /*unused*/)
6310 {
6311 handle_value(val);
6312 return true;
6313 }
6314
6315 bool string(string_t& val)
6316 {
6317 handle_value(val);
6318 return true;
6319 }
6320
6321 bool binary(binary_t& val)
6322 {
6323 handle_value(std::move(val));
6324 return true;
6325 }
6326
6327 bool start_object(std::size_t len)
6328 {
6329 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6330
6331 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6332 {
6333 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6334 }
6335
6336 return true;
6337 }
6338
6339 bool key(string_t& val)
6340 {
6341 JSON_ASSERT(!ref_stack.empty());
6342 JSON_ASSERT(ref_stack.back()->is_object());
6343
6344 // add null at given key and store the reference for later
6345 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6346 return true;
6347 }
6348
6350 {
6351 JSON_ASSERT(!ref_stack.empty());
6352 JSON_ASSERT(ref_stack.back()->is_object());
6353
6354 ref_stack.back()->set_parents();
6355 ref_stack.pop_back();
6356 return true;
6357 }
6358
6359 bool start_array(std::size_t len)
6360 {
6361 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6362
6363 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6364 {
6365 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6366 }
6367
6368 return true;
6369 }
6370
6372 {
6373 JSON_ASSERT(!ref_stack.empty());
6374 JSON_ASSERT(ref_stack.back()->is_array());
6375
6376 ref_stack.back()->set_parents();
6377 ref_stack.pop_back();
6378 return true;
6379 }
6380
6381 template<class Exception>
6382 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6383 const Exception& ex)
6384 {
6385 errored = true;
6386 static_cast<void>(ex);
6387 if (allow_exceptions)
6388 {
6389 JSON_THROW(ex);
6390 }
6391 return false;
6392 }
6393
6394 constexpr bool is_errored() const
6395 {
6396 return errored;
6397 }
6398
6399 private:
6406 template<typename Value>
6408 BasicJsonType* handle_value(Value&& v)
6409 {
6410 if (ref_stack.empty())
6411 {
6412 root = BasicJsonType(std::forward<Value>(v));
6413 return &root;
6414 }
6415
6416 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6417
6418 if (ref_stack.back()->is_array())
6419 {
6420 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6421 return &(ref_stack.back()->m_value.array->back());
6422 }
6423
6424 JSON_ASSERT(ref_stack.back()->is_object());
6425 JSON_ASSERT(object_element);
6426 *object_element = BasicJsonType(std::forward<Value>(v));
6427 return object_element;
6428 }
6429
6431 BasicJsonType& root;
6433 std::vector<BasicJsonType*> ref_stack{};
6435 BasicJsonType* object_element = nullptr;
6437 bool errored = false;
6439 const bool allow_exceptions = true;
6440 };
6441
6442 template<typename BasicJsonType>
6444 {
6445 public:
6446 using number_integer_t = typename BasicJsonType::number_integer_t;
6447 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6448 using number_float_t = typename BasicJsonType::number_float_t;
6449 using string_t = typename BasicJsonType::string_t;
6450 using binary_t = typename BasicJsonType::binary_t;
6453
6455 const parser_callback_t cb,
6456 const bool allow_exceptions_ = true)
6457 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6458 {
6459 keep_stack.push_back(true);
6460 }
6461
6462 // make class move-only
6464 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6466 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6468
6469 bool null()
6470 {
6471 handle_value(nullptr);
6472 return true;
6473 }
6474
6475 bool boolean(bool val)
6476 {
6477 handle_value(val);
6478 return true;
6479 }
6480
6482 {
6483 handle_value(val);
6484 return true;
6485 }
6486
6488 {
6489 handle_value(val);
6490 return true;
6491 }
6492
6493 bool number_float(number_float_t val, const string_t& /*unused*/)
6494 {
6495 handle_value(val);
6496 return true;
6497 }
6498
6499 bool string(string_t& val)
6500 {
6501 handle_value(val);
6502 return true;
6503 }
6504
6505 bool binary(binary_t& val)
6506 {
6507 handle_value(std::move(val));
6508 return true;
6509 }
6510
6511 bool start_object(std::size_t len)
6512 {
6513 // check callback for object start
6514 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6515 keep_stack.push_back(keep);
6516
6517 auto val = handle_value(BasicJsonType::value_t::object, true);
6518 ref_stack.push_back(val.second);
6519
6520 // check object limit
6521 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6522 {
6523 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6524 }
6525
6526 return true;
6527 }
6528
6529 bool key(string_t& val)
6530 {
6531 BasicJsonType k = BasicJsonType(val);
6532
6533 // check callback for key
6534 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6535 key_keep_stack.push_back(keep);
6536
6537 // add discarded value at given key and store the reference for later
6538 if (keep && ref_stack.back())
6539 {
6540 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6541 }
6542
6543 return true;
6544 }
6545
6547 {
6548 if (ref_stack.back())
6549 {
6550 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6551 {
6552 // discard object
6553 *ref_stack.back() = discarded;
6554 }
6555 else
6556 {
6557 ref_stack.back()->set_parents();
6558 }
6559 }
6560
6561 JSON_ASSERT(!ref_stack.empty());
6562 JSON_ASSERT(!keep_stack.empty());
6563 ref_stack.pop_back();
6564 keep_stack.pop_back();
6565
6566 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6567 {
6568 // remove discarded value
6569 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6570 {
6571 if (it->is_discarded())
6572 {
6573 ref_stack.back()->erase(it);
6574 break;
6575 }
6576 }
6577 }
6578
6579 return true;
6580 }
6581
6582 bool start_array(std::size_t len)
6583 {
6584 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6585 keep_stack.push_back(keep);
6586
6587 auto val = handle_value(BasicJsonType::value_t::array, true);
6588 ref_stack.push_back(val.second);
6589
6590 // check array limit
6591 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6592 {
6593 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6594 }
6595
6596 return true;
6597 }
6598
6600 {
6601 bool keep = true;
6602
6603 if (ref_stack.back())
6604 {
6605 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6606 if (keep)
6607 {
6608 ref_stack.back()->set_parents();
6609 }
6610 else
6611 {
6612 // discard array
6613 *ref_stack.back() = discarded;
6614 }
6615 }
6616
6617 JSON_ASSERT(!ref_stack.empty());
6618 JSON_ASSERT(!keep_stack.empty());
6619 ref_stack.pop_back();
6620 keep_stack.pop_back();
6621
6622 // remove discarded value
6623 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6624 {
6625 ref_stack.back()->m_value.array->pop_back();
6626 }
6627
6628 return true;
6629 }
6630
6631 template<class Exception>
6632 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6633 const Exception& ex)
6634 {
6635 errored = true;
6636 static_cast<void>(ex);
6637 if (allow_exceptions)
6638 {
6639 JSON_THROW(ex);
6640 }
6641 return false;
6642 }
6643
6644 constexpr bool is_errored() const
6645 {
6646 return errored;
6647 }
6648
6649 private:
6665 template<typename Value>
6666 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6667 {
6668 JSON_ASSERT(!keep_stack.empty());
6669
6670 // do not handle this value if we know it would be added to a discarded
6671 // container
6672 if (!keep_stack.back())
6673 {
6674 return { false, nullptr };
6675 }
6676
6677 // create value
6678 auto value = BasicJsonType(std::forward<Value>(v));
6679
6680 // check callback
6681 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6682
6683 // do not handle this value if we just learnt it shall be discarded
6684 if (!keep)
6685 {
6686 return { false, nullptr };
6687 }
6688
6689 if (ref_stack.empty())
6690 {
6691 root = std::move(value);
6692 return { true, &root };
6693 }
6694
6695 // skip this value if we already decided to skip the parent
6696 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6697 if (!ref_stack.back())
6698 {
6699 return { false, nullptr };
6700 }
6701
6702 // we now only expect arrays and objects
6703 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6704
6705 // array
6706 if (ref_stack.back()->is_array())
6707 {
6708 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6709 return { true, &(ref_stack.back()->m_value.array->back()) };
6710 }
6711
6712 // object
6713 JSON_ASSERT(ref_stack.back()->is_object());
6714 // check if we should store an element for the current key
6715 JSON_ASSERT(!key_keep_stack.empty());
6716 const bool store_element = key_keep_stack.back();
6717 key_keep_stack.pop_back();
6718
6719 if (!store_element)
6720 {
6721 return { false, nullptr };
6722 }
6723
6724 JSON_ASSERT(object_element);
6725 *object_element = std::move(value);
6726 return { true, object_element };
6727 }
6728
6730 BasicJsonType& root;
6732 std::vector<BasicJsonType*> ref_stack{};
6734 std::vector<bool> keep_stack{};
6736 std::vector<bool> key_keep_stack{};
6738 BasicJsonType* object_element = nullptr;
6740 bool errored = false;
6742 const parser_callback_t callback = nullptr;
6744 const bool allow_exceptions = true;
6746 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6747 };
6748
6749 template<typename BasicJsonType>
6751 {
6752 public:
6753 using number_integer_t = typename BasicJsonType::number_integer_t;
6754 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6755 using number_float_t = typename BasicJsonType::number_float_t;
6756 using string_t = typename BasicJsonType::string_t;
6757 using binary_t = typename BasicJsonType::binary_t;
6758
6759 bool null()
6760 {
6761 return true;
6762 }
6763
6764 bool boolean(bool /*unused*/)
6765 {
6766 return true;
6767 }
6768
6770 {
6771 return true;
6772 }
6773
6775 {
6776 return true;
6777 }
6778
6779 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6780 {
6781 return true;
6782 }
6783
6784 bool string(string_t& /*unused*/)
6785 {
6786 return true;
6787 }
6788
6789 bool binary(binary_t& /*unused*/)
6790 {
6791 return true;
6792 }
6793
6794 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6795 {
6796 return true;
6797 }
6798
6799 bool key(string_t& /*unused*/)
6800 {
6801 return true;
6802 }
6803
6805 {
6806 return true;
6807 }
6808
6809 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6810 {
6811 return true;
6812 }
6813
6815 {
6816 return true;
6817 }
6818
6819 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6820 {
6821 return false;
6822 }
6823 };
6824 } // namespace detail
6825
6826} // namespace nlohmann
6827
6828// #include <nlohmann/detail/input/lexer.hpp>
6829
6830
6831#include <array> // array
6832#include <clocale> // localeconv
6833#include <cstddef> // size_t
6834#include <cstdio> // snprintf
6835#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6836#include <initializer_list> // initializer_list
6837#include <string> // char_traits, string
6838#include <utility> // move
6839#include <vector> // vector
6840
6841// #include <nlohmann/detail/input/input_adapters.hpp>
6842
6843// #include <nlohmann/detail/input/position_t.hpp>
6844
6845// #include <nlohmann/detail/macro_scope.hpp>
6846
6847
6848namespace nlohmann
6849{
6850 namespace detail
6851 {
6853 // lexer //
6855
6856 template<typename BasicJsonType>
6858 {
6859 public:
6861 enum class token_type
6862 {
6863 uninitialized,
6864 literal_true,
6865 literal_false,
6866 literal_null,
6867 value_string,
6868 value_unsigned,
6869 value_integer,
6870 value_float,
6871 begin_array,
6872 begin_object,
6873 end_array,
6874 end_object,
6875 name_separator,
6876 value_separator,
6877 parse_error,
6878 end_of_input,
6879 literal_or_value
6880 };
6881
6885 static const char* token_type_name(const token_type t) noexcept
6886 {
6887 switch (t)
6888 {
6890 return "<uninitialized>";
6892 return "true literal";
6894 return "false literal";
6896 return "null literal";
6898 return "string literal";
6902 return "number literal";
6904 return "'['";
6906 return "'{'";
6908 return "']'";
6910 return "'}'";
6912 return "':'";
6914 return "','";
6916 return "<parse error>";
6918 return "end of input";
6920 return "'[', '{', or a literal";
6921 // LCOV_EXCL_START
6922 default: // catch non-enum values
6923 return "unknown token";
6924 // LCOV_EXCL_STOP
6925 }
6926 }
6927 };
6933 template<typename BasicJsonType, typename InputAdapterType>
6934 class lexer : public lexer_base<BasicJsonType>
6935 {
6936 using number_integer_t = typename BasicJsonType::number_integer_t;
6937 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6938 using number_float_t = typename BasicJsonType::number_float_t;
6939 using string_t = typename BasicJsonType::string_t;
6940 using char_type = typename InputAdapterType::char_type;
6941 using char_int_type = typename std::char_traits<char_type>::int_type;
6942
6943 public:
6945
6946 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6947 : ia(std::move(adapter))
6948 , ignore_comments(ignore_comments_)
6949 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6950 {}
6951
6952 // delete because of pointer members
6953 lexer(const lexer&) = delete;
6954 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6955 lexer& operator=(lexer&) = delete;
6956 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6957 ~lexer() = default;
6958
6959 private:
6961 // locales
6963
6966 static char get_decimal_point() noexcept
6967 {
6968 const auto* loc = localeconv();
6969 JSON_ASSERT(loc != nullptr);
6970 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6971 }
6972
6974 // scan functions
6976
6992 int get_codepoint()
6993 {
6994 // this function only makes sense after reading `\u`
6995 JSON_ASSERT(current == 'u');
6996 int codepoint = 0;
6997
6998 const auto factors = { 12u, 8u, 4u, 0u };
6999 for (const auto factor : factors)
7000 {
7001 get();
7002
7003 if (current >= '0' && current <= '9')
7004 {
7005 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7006 }
7007 else if (current >= 'A' && current <= 'F')
7008 {
7009 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7010 }
7011 else if (current >= 'a' && current <= 'f')
7012 {
7013 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7014 }
7015 else
7016 {
7017 return -1;
7018 }
7019 }
7020
7021 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7022 return codepoint;
7023 }
7024
7040 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7041 {
7042 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7043 add(current);
7044
7045 for (auto range = ranges.begin(); range != ranges.end(); ++range)
7046 {
7047 get();
7048 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
7049 {
7050 add(current);
7051 }
7052 else
7053 {
7054 error_message = "invalid string: ill-formed UTF-8 byte";
7055 return false;
7056 }
7057 }
7058
7059 return true;
7060 }
7061
7077 token_type scan_string()
7078 {
7079 // reset token_buffer (ignore opening quote)
7080 reset();
7081
7082 // we entered the function by reading an open quote
7083 JSON_ASSERT(current == '\"');
7084
7085 while (true)
7086 {
7087 // get next character
7088 switch (get())
7089 {
7090 // end of file while parsing string
7091 case std::char_traits<char_type>::eof():
7092 {
7093 error_message = "invalid string: missing closing quote";
7094 return token_type::parse_error;
7095 }
7096
7097 // closing quote
7098 case '\"':
7099 {
7100 return token_type::value_string;
7101 }
7102
7103 // escapes
7104 case '\\':
7105 {
7106 switch (get())
7107 {
7108 // quotation mark
7109 case '\"':
7110 add('\"');
7111 break;
7112 // reverse solidus
7113 case '\\':
7114 add('\\');
7115 break;
7116 // solidus
7117 case '/':
7118 add('/');
7119 break;
7120 // backspace
7121 case 'b':
7122 add('\b');
7123 break;
7124 // form feed
7125 case 'f':
7126 add('\f');
7127 break;
7128 // line feed
7129 case 'n':
7130 add('\n');
7131 break;
7132 // carriage return
7133 case 'r':
7134 add('\r');
7135 break;
7136 // tab
7137 case 't':
7138 add('\t');
7139 break;
7140
7141 // unicode escapes
7142 case 'u':
7143 {
7144 const int codepoint1 = get_codepoint();
7145 int codepoint = codepoint1; // start with codepoint1
7146
7147 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7148 {
7149 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7150 return token_type::parse_error;
7151 }
7152
7153 // check if code point is a high surrogate
7154 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7155 {
7156 // expect next \uxxxx entry
7157 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7158 {
7159 const int codepoint2 = get_codepoint();
7160
7161 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7162 {
7163 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7164 return token_type::parse_error;
7165 }
7166
7167 // check if codepoint2 is a low surrogate
7168 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7169 {
7170 // overwrite codepoint
7171 codepoint = static_cast<int>(
7172 // high surrogate occupies the most significant 22 bits
7173 (static_cast<unsigned int>(codepoint1) << 10u)
7174 // low surrogate occupies the least significant 15 bits
7175 + static_cast<unsigned int>(codepoint2)
7176 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7177 // in the result, so we have to subtract with:
7178 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7179 -0x35FDC00u);
7180 }
7181 else
7182 {
7183 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7184 return token_type::parse_error;
7185 }
7186 }
7187 else
7188 {
7189 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7190 return token_type::parse_error;
7191 }
7192 }
7193 else
7194 {
7195 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7196 {
7197 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7198 return token_type::parse_error;
7199 }
7200 }
7201
7202 // result of the above calculation yields a proper codepoint
7203 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7204
7205 // translate codepoint into bytes
7206 if (codepoint < 0x80)
7207 {
7208 // 1-byte characters: 0xxxxxxx (ASCII)
7209 add(static_cast<char_int_type>(codepoint));
7210 }
7211 else if (codepoint <= 0x7FF)
7212 {
7213 // 2-byte characters: 110xxxxx 10xxxxxx
7214 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7215 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7216 }
7217 else if (codepoint <= 0xFFFF)
7218 {
7219 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7220 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7221 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7222 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7223 }
7224 else
7225 {
7226 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7227 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7228 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7229 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7230 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7231 }
7232
7233 break;
7234 }
7235
7236 // other characters after escape
7237 default:
7238 error_message = "invalid string: forbidden character after backslash";
7239 return token_type::parse_error;
7240 }
7241
7242 break;
7243 }
7244
7245 // invalid control characters
7246 case 0x00:
7247 {
7248 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7249 return token_type::parse_error;
7250 }
7251
7252 case 0x01:
7253 {
7254 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7255 return token_type::parse_error;
7256 }
7257
7258 case 0x02:
7259 {
7260 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7261 return token_type::parse_error;
7262 }
7263
7264 case 0x03:
7265 {
7266 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7267 return token_type::parse_error;
7268 }
7269
7270 case 0x04:
7271 {
7272 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7273 return token_type::parse_error;
7274 }
7275
7276 case 0x05:
7277 {
7278 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7279 return token_type::parse_error;
7280 }
7281
7282 case 0x06:
7283 {
7284 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7285 return token_type::parse_error;
7286 }
7287
7288 case 0x07:
7289 {
7290 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7291 return token_type::parse_error;
7292 }
7293
7294 case 0x08:
7295 {
7296 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7297 return token_type::parse_error;
7298 }
7299
7300 case 0x09:
7301 {
7302 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7303 return token_type::parse_error;
7304 }
7305
7306 case 0x0A:
7307 {
7308 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7309 return token_type::parse_error;
7310 }
7311
7312 case 0x0B:
7313 {
7314 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7315 return token_type::parse_error;
7316 }
7317
7318 case 0x0C:
7319 {
7320 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7321 return token_type::parse_error;
7322 }
7323
7324 case 0x0D:
7325 {
7326 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7327 return token_type::parse_error;
7328 }
7329
7330 case 0x0E:
7331 {
7332 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7333 return token_type::parse_error;
7334 }
7335
7336 case 0x0F:
7337 {
7338 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7339 return token_type::parse_error;
7340 }
7341
7342 case 0x10:
7343 {
7344 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7345 return token_type::parse_error;
7346 }
7347
7348 case 0x11:
7349 {
7350 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7351 return token_type::parse_error;
7352 }
7353
7354 case 0x12:
7355 {
7356 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7357 return token_type::parse_error;
7358 }
7359
7360 case 0x13:
7361 {
7362 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7363 return token_type::parse_error;
7364 }
7365
7366 case 0x14:
7367 {
7368 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7369 return token_type::parse_error;
7370 }
7371
7372 case 0x15:
7373 {
7374 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7375 return token_type::parse_error;
7376 }
7377
7378 case 0x16:
7379 {
7380 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7381 return token_type::parse_error;
7382 }
7383
7384 case 0x17:
7385 {
7386 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7387 return token_type::parse_error;
7388 }
7389
7390 case 0x18:
7391 {
7392 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7393 return token_type::parse_error;
7394 }
7395
7396 case 0x19:
7397 {
7398 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7399 return token_type::parse_error;
7400 }
7401
7402 case 0x1A:
7403 {
7404 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7405 return token_type::parse_error;
7406 }
7407
7408 case 0x1B:
7409 {
7410 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7411 return token_type::parse_error;
7412 }
7413
7414 case 0x1C:
7415 {
7416 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7417 return token_type::parse_error;
7418 }
7419
7420 case 0x1D:
7421 {
7422 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7423 return token_type::parse_error;
7424 }
7425
7426 case 0x1E:
7427 {
7428 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7429 return token_type::parse_error;
7430 }
7431
7432 case 0x1F:
7433 {
7434 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7435 return token_type::parse_error;
7436 }
7437
7438 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7439 case 0x20:
7440 case 0x21:
7441 case 0x23:
7442 case 0x24:
7443 case 0x25:
7444 case 0x26:
7445 case 0x27:
7446 case 0x28:
7447 case 0x29:
7448 case 0x2A:
7449 case 0x2B:
7450 case 0x2C:
7451 case 0x2D:
7452 case 0x2E:
7453 case 0x2F:
7454 case 0x30:
7455 case 0x31:
7456 case 0x32:
7457 case 0x33:
7458 case 0x34:
7459 case 0x35:
7460 case 0x36:
7461 case 0x37:
7462 case 0x38:
7463 case 0x39:
7464 case 0x3A:
7465 case 0x3B:
7466 case 0x3C:
7467 case 0x3D:
7468 case 0x3E:
7469 case 0x3F:
7470 case 0x40:
7471 case 0x41:
7472 case 0x42:
7473 case 0x43:
7474 case 0x44:
7475 case 0x45:
7476 case 0x46:
7477 case 0x47:
7478 case 0x48:
7479 case 0x49:
7480 case 0x4A:
7481 case 0x4B:
7482 case 0x4C:
7483 case 0x4D:
7484 case 0x4E:
7485 case 0x4F:
7486 case 0x50:
7487 case 0x51:
7488 case 0x52:
7489 case 0x53:
7490 case 0x54:
7491 case 0x55:
7492 case 0x56:
7493 case 0x57:
7494 case 0x58:
7495 case 0x59:
7496 case 0x5A:
7497 case 0x5B:
7498 case 0x5D:
7499 case 0x5E:
7500 case 0x5F:
7501 case 0x60:
7502 case 0x61:
7503 case 0x62:
7504 case 0x63:
7505 case 0x64:
7506 case 0x65:
7507 case 0x66:
7508 case 0x67:
7509 case 0x68:
7510 case 0x69:
7511 case 0x6A:
7512 case 0x6B:
7513 case 0x6C:
7514 case 0x6D:
7515 case 0x6E:
7516 case 0x6F:
7517 case 0x70:
7518 case 0x71:
7519 case 0x72:
7520 case 0x73:
7521 case 0x74:
7522 case 0x75:
7523 case 0x76:
7524 case 0x77:
7525 case 0x78:
7526 case 0x79:
7527 case 0x7A:
7528 case 0x7B:
7529 case 0x7C:
7530 case 0x7D:
7531 case 0x7E:
7532 case 0x7F:
7533 {
7534 add(current);
7535 break;
7536 }
7537
7538 // U+0080..U+07FF: bytes C2..DF 80..BF
7539 case 0xC2:
7540 case 0xC3:
7541 case 0xC4:
7542 case 0xC5:
7543 case 0xC6:
7544 case 0xC7:
7545 case 0xC8:
7546 case 0xC9:
7547 case 0xCA:
7548 case 0xCB:
7549 case 0xCC:
7550 case 0xCD:
7551 case 0xCE:
7552 case 0xCF:
7553 case 0xD0:
7554 case 0xD1:
7555 case 0xD2:
7556 case 0xD3:
7557 case 0xD4:
7558 case 0xD5:
7559 case 0xD6:
7560 case 0xD7:
7561 case 0xD8:
7562 case 0xD9:
7563 case 0xDA:
7564 case 0xDB:
7565 case 0xDC:
7566 case 0xDD:
7567 case 0xDE:
7568 case 0xDF:
7569 {
7570 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({ 0x80, 0xBF })))
7571 {
7572 return token_type::parse_error;
7573 }
7574 break;
7575 }
7576
7577 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7578 case 0xE0:
7579 {
7580 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0xA0, 0xBF, 0x80, 0xBF }))))
7581 {
7582 return token_type::parse_error;
7583 }
7584 break;
7585 }
7586
7587 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7588 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7589 case 0xE1:
7590 case 0xE2:
7591 case 0xE3:
7592 case 0xE4:
7593 case 0xE5:
7594 case 0xE6:
7595 case 0xE7:
7596 case 0xE8:
7597 case 0xE9:
7598 case 0xEA:
7599 case 0xEB:
7600 case 0xEC:
7601 case 0xEE:
7602 case 0xEF:
7603 {
7604 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF }))))
7605 {
7606 return token_type::parse_error;
7607 }
7608 break;
7609 }
7610
7611 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7612 case 0xED:
7613 {
7614 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x9F, 0x80, 0xBF }))))
7615 {
7616 return token_type::parse_error;
7617 }
7618 break;
7619 }
7620
7621 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7622 case 0xF0:
7623 {
7624 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
7625 {
7626 return token_type::parse_error;
7627 }
7628 break;
7629 }
7630
7631 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7632 case 0xF1:
7633 case 0xF2:
7634 case 0xF3:
7635 {
7636 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
7637 {
7638 return token_type::parse_error;
7639 }
7640 break;
7641 }
7642
7643 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7644 case 0xF4:
7645 {
7646 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF }))))
7647 {
7648 return token_type::parse_error;
7649 }
7650 break;
7651 }
7652
7653 // remaining bytes (80..C1 and F5..FF) are ill-formed
7654 default:
7655 {
7656 error_message = "invalid string: ill-formed UTF-8 byte";
7657 return token_type::parse_error;
7658 }
7659 }
7660 }
7661 }
7662
7667 bool scan_comment()
7668 {
7669 switch (get())
7670 {
7671 // single-line comments skip input until a newline or EOF is read
7672 case '/':
7673 {
7674 while (true)
7675 {
7676 switch (get())
7677 {
7678 case '\n':
7679 case '\r':
7680 case std::char_traits<char_type>::eof():
7681 case '\0':
7682 return true;
7683
7684 default:
7685 break;
7686 }
7687 }
7688 }
7689
7690 // multi-line comments skip input until */ is read
7691 case '*':
7692 {
7693 while (true)
7694 {
7695 switch (get())
7696 {
7697 case std::char_traits<char_type>::eof():
7698 case '\0':
7699 {
7700 error_message = "invalid comment; missing closing '*/'";
7701 return false;
7702 }
7703
7704 case '*':
7705 {
7706 switch (get())
7707 {
7708 case '/':
7709 return true;
7710
7711 default:
7712 {
7713 unget();
7714 continue;
7715 }
7716 }
7717 }
7718
7719 default:
7720 continue;
7721 }
7722 }
7723 }
7724
7725 // unexpected character after reading '/'
7726 default:
7727 {
7728 error_message = "invalid comment; expecting '/' or '*' after '/'";
7729 return false;
7730 }
7731 }
7732 }
7733
7735 static void strtof(float& f, const char* str, char** endptr) noexcept
7736 {
7737 f = std::strtof(str, endptr);
7738 }
7739
7741 static void strtof(double& f, const char* str, char** endptr) noexcept
7742 {
7743 f = std::strtod(str, endptr);
7744 }
7745
7747 static void strtof(long double& f, const char* str, char** endptr) noexcept
7748 {
7749 f = std::strtold(str, endptr);
7750 }
7751
7792 token_type scan_number() // lgtm [cpp/use-of-goto]
7793 {
7794 // reset token_buffer to store the number's bytes
7795 reset();
7796
7797 // the type of the parsed number; initially set to unsigned; will be
7798 // changed if minus sign, decimal point or exponent is read
7799 token_type number_type = token_type::value_unsigned;
7800
7801 // state (init): we just found out we need to scan a number
7802 switch (current)
7803 {
7804 case '-':
7805 {
7806 add(current);
7807 goto scan_number_minus;
7808 }
7809
7810 case '0':
7811 {
7812 add(current);
7813 goto scan_number_zero;
7814 }
7815
7816 case '1':
7817 case '2':
7818 case '3':
7819 case '4':
7820 case '5':
7821 case '6':
7822 case '7':
7823 case '8':
7824 case '9':
7825 {
7826 add(current);
7827 goto scan_number_any1;
7828 }
7829
7830 // all other characters are rejected outside scan_number()
7831 default: // LCOV_EXCL_LINE
7832 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7833 }
7834
7835 scan_number_minus:
7836 // state: we just parsed a leading minus sign
7837 number_type = token_type::value_integer;
7838 switch (get())
7839 {
7840 case '0':
7841 {
7842 add(current);
7843 goto scan_number_zero;
7844 }
7845
7846 case '1':
7847 case '2':
7848 case '3':
7849 case '4':
7850 case '5':
7851 case '6':
7852 case '7':
7853 case '8':
7854 case '9':
7855 {
7856 add(current);
7857 goto scan_number_any1;
7858 }
7859
7860 default:
7861 {
7862 error_message = "invalid number; expected digit after '-'";
7863 return token_type::parse_error;
7864 }
7865 }
7866
7867 scan_number_zero:
7868 // state: we just parse a zero (maybe with a leading minus sign)
7869 switch (get())
7870 {
7871 case '.':
7872 {
7873 add(decimal_point_char);
7874 goto scan_number_decimal1;
7875 }
7876
7877 case 'e':
7878 case 'E':
7879 {
7880 add(current);
7881 goto scan_number_exponent;
7882 }
7883
7884 default:
7885 goto scan_number_done;
7886 }
7887
7888 scan_number_any1:
7889 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7890 switch (get())
7891 {
7892 case '0':
7893 case '1':
7894 case '2':
7895 case '3':
7896 case '4':
7897 case '5':
7898 case '6':
7899 case '7':
7900 case '8':
7901 case '9':
7902 {
7903 add(current);
7904 goto scan_number_any1;
7905 }
7906
7907 case '.':
7908 {
7909 add(decimal_point_char);
7910 goto scan_number_decimal1;
7911 }
7912
7913 case 'e':
7914 case 'E':
7915 {
7916 add(current);
7917 goto scan_number_exponent;
7918 }
7919
7920 default:
7921 goto scan_number_done;
7922 }
7923
7924 scan_number_decimal1:
7925 // state: we just parsed a decimal point
7926 number_type = token_type::value_float;
7927 switch (get())
7928 {
7929 case '0':
7930 case '1':
7931 case '2':
7932 case '3':
7933 case '4':
7934 case '5':
7935 case '6':
7936 case '7':
7937 case '8':
7938 case '9':
7939 {
7940 add(current);
7941 goto scan_number_decimal2;
7942 }
7943
7944 default:
7945 {
7946 error_message = "invalid number; expected digit after '.'";
7947 return token_type::parse_error;
7948 }
7949 }
7950
7951 scan_number_decimal2:
7952 // we just parsed at least one number after a decimal point
7953 switch (get())
7954 {
7955 case '0':
7956 case '1':
7957 case '2':
7958 case '3':
7959 case '4':
7960 case '5':
7961 case '6':
7962 case '7':
7963 case '8':
7964 case '9':
7965 {
7966 add(current);
7967 goto scan_number_decimal2;
7968 }
7969
7970 case 'e':
7971 case 'E':
7972 {
7973 add(current);
7974 goto scan_number_exponent;
7975 }
7976
7977 default:
7978 goto scan_number_done;
7979 }
7980
7981 scan_number_exponent:
7982 // we just parsed an exponent
7983 number_type = token_type::value_float;
7984 switch (get())
7985 {
7986 case '+':
7987 case '-':
7988 {
7989 add(current);
7990 goto scan_number_sign;
7991 }
7992
7993 case '0':
7994 case '1':
7995 case '2':
7996 case '3':
7997 case '4':
7998 case '5':
7999 case '6':
8000 case '7':
8001 case '8':
8002 case '9':
8003 {
8004 add(current);
8005 goto scan_number_any2;
8006 }
8007
8008 default:
8009 {
8010 error_message =
8011 "invalid number; expected '+', '-', or digit after exponent";
8012 return token_type::parse_error;
8013 }
8014 }
8015
8016 scan_number_sign:
8017 // we just parsed an exponent sign
8018 switch (get())
8019 {
8020 case '0':
8021 case '1':
8022 case '2':
8023 case '3':
8024 case '4':
8025 case '5':
8026 case '6':
8027 case '7':
8028 case '8':
8029 case '9':
8030 {
8031 add(current);
8032 goto scan_number_any2;
8033 }
8034
8035 default:
8036 {
8037 error_message = "invalid number; expected digit after exponent sign";
8038 return token_type::parse_error;
8039 }
8040 }
8041
8042 scan_number_any2:
8043 // we just parsed a number after the exponent or exponent sign
8044 switch (get())
8045 {
8046 case '0':
8047 case '1':
8048 case '2':
8049 case '3':
8050 case '4':
8051 case '5':
8052 case '6':
8053 case '7':
8054 case '8':
8055 case '9':
8056 {
8057 add(current);
8058 goto scan_number_any2;
8059 }
8060
8061 default:
8062 goto scan_number_done;
8063 }
8064
8065 scan_number_done:
8066 // unget the character after the number (we only read it to know that
8067 // we are done scanning a number)
8068 unget();
8069
8070 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8071 errno = 0;
8072
8073 // try to parse integers first and fall back to floats
8074 if (number_type == token_type::value_unsigned)
8075 {
8076 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8077
8078 // we checked the number format before
8079 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8080
8081 if (errno == 0)
8082 {
8083 value_unsigned = static_cast<number_unsigned_t>(x);
8084 if (value_unsigned == x)
8085 {
8086 return token_type::value_unsigned;
8087 }
8088 }
8089 }
8090 else if (number_type == token_type::value_integer)
8091 {
8092 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8093
8094 // we checked the number format before
8095 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8096
8097 if (errno == 0)
8098 {
8099 value_integer = static_cast<number_integer_t>(x);
8100 if (value_integer == x)
8101 {
8102 return token_type::value_integer;
8103 }
8104 }
8105 }
8106
8107 // this code is reached if we parse a floating-point number or if an
8108 // integer conversion above failed
8109 strtof(value_float, token_buffer.data(), &endptr);
8110
8111 // we checked the number format before
8112 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8113
8114 return token_type::value_float;
8115 }
8116
8123 token_type scan_literal(const char_type* literal_text, const std::size_t length,
8124 token_type return_type)
8125 {
8126 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8127 for (std::size_t i = 1; i < length; ++i)
8128 {
8129 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8130 {
8131 error_message = "invalid literal";
8132 return token_type::parse_error;
8133 }
8134 }
8135 return return_type;
8136 }
8137
8139 // input management
8141
8143 void reset() noexcept
8144 {
8145 token_buffer.clear();
8146 token_string.clear();
8147 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8148 }
8149
8150 /*
8151 @brief get next character from the input
8152
8153 This function provides the interface to the used input adapter. It does
8154 not throw in case the input reached EOF, but returns a
8155 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8156 for use in error messages.
8157
8158 @return character read from the input
8159 */
8160 char_int_type get()
8161 {
8162 ++position.chars_read_total;
8163 ++position.chars_read_current_line;
8164
8165 if (next_unget)
8166 {
8167 // just reset the next_unget variable and work with current
8168 next_unget = false;
8169 }
8170 else
8171 {
8172 current = ia.get_character();
8173 }
8174
8175 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8176 {
8177 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8178 }
8179
8180 if (current == '\n')
8181 {
8182 ++position.lines_read;
8183 position.chars_read_current_line = 0;
8184 }
8185
8186 return current;
8187 }
8188
8197 void unget()
8198 {
8199 next_unget = true;
8200
8201 --position.chars_read_total;
8202
8203 // in case we "unget" a newline, we have to also decrement the lines_read
8204 if (position.chars_read_current_line == 0)
8205 {
8206 if (position.lines_read > 0)
8207 {
8208 --position.lines_read;
8209 }
8210 }
8211 else
8212 {
8213 --position.chars_read_current_line;
8214 }
8215
8216 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8217 {
8218 JSON_ASSERT(!token_string.empty());
8219 token_string.pop_back();
8220 }
8221 }
8222
8224 void add(char_int_type c)
8225 {
8226 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8227 }
8228
8229 public:
8231 // value getters
8233
8235 constexpr number_integer_t get_number_integer() const noexcept
8236 {
8237 return value_integer;
8238 }
8239
8241 constexpr number_unsigned_t get_number_unsigned() const noexcept
8242 {
8243 return value_unsigned;
8244 }
8245
8247 constexpr number_float_t get_number_float() const noexcept
8248 {
8249 return value_float;
8250 }
8251
8253 string_t& get_string()
8254 {
8255 return token_buffer;
8256 }
8257
8259 // diagnostics
8261
8263 constexpr position_t get_position() const noexcept
8264 {
8265 return position;
8266 }
8267
8271 std::string get_token_string() const
8272 {
8273 // escape control characters
8274 std::string result;
8275 for (const auto c : token_string)
8276 {
8277 if (static_cast<unsigned char>(c) <= '\x1F')
8278 {
8279 // escape control characters
8280 std::array<char, 9> cs{ {} };
8281 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8282 result += cs.data();
8283 }
8284 else
8285 {
8286 // add character as is
8287 result.push_back(static_cast<std::string::value_type>(c));
8288 }
8289 }
8290
8291 return result;
8292 }
8293
8296 constexpr const char* get_error_message() const noexcept
8297 {
8298 return error_message;
8299 }
8300
8302 // actual scanner
8304
8310 {
8311 if (get() == 0xEF)
8312 {
8313 // check if we completely parse the BOM
8314 return get() == 0xBB && get() == 0xBF;
8315 }
8316
8317 // the first character is not the beginning of the BOM; unget it to
8318 // process is later
8319 unget();
8320 return true;
8321 }
8322
8324 {
8325 do
8326 {
8327 get();
8328 } while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8329 }
8330
8332 {
8333 // initially, skip the BOM
8334 if (position.chars_read_total == 0 && !skip_bom())
8335 {
8336 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8337 return token_type::parse_error;
8338 }
8339
8340 // read next character and ignore whitespace
8341 skip_whitespace();
8342
8343 // ignore comments
8344 while (ignore_comments && current == '/')
8345 {
8346 if (!scan_comment())
8347 {
8348 return token_type::parse_error;
8349 }
8350
8351 // skip following whitespace
8352 skip_whitespace();
8353 }
8354
8355 switch (current)
8356 {
8357 // structural characters
8358 case '[':
8359 return token_type::begin_array;
8360 case ']':
8361 return token_type::end_array;
8362 case '{':
8363 return token_type::begin_object;
8364 case '}':
8365 return token_type::end_object;
8366 case ':':
8367 return token_type::name_separator;
8368 case ',':
8369 return token_type::value_separator;
8370
8371 // literals
8372 case 't':
8373 {
8374 std::array<char_type, 4> true_literal = { {static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')} };
8375 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8376 }
8377 case 'f':
8378 {
8379 std::array<char_type, 5> false_literal = { {static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')} };
8380 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8381 }
8382 case 'n':
8383 {
8384 std::array<char_type, 4> null_literal = { {static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')} };
8385 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8386 }
8387
8388 // string
8389 case '\"':
8390 return scan_string();
8391
8392 // number
8393 case '-':
8394 case '0':
8395 case '1':
8396 case '2':
8397 case '3':
8398 case '4':
8399 case '5':
8400 case '6':
8401 case '7':
8402 case '8':
8403 case '9':
8404 return scan_number();
8405
8406 // end of input (the null byte is needed when parsing from
8407 // string literals)
8408 case '\0':
8409 case std::char_traits<char_type>::eof():
8410 return token_type::end_of_input;
8411
8412 // error
8413 default:
8414 error_message = "invalid literal";
8415 return token_type::parse_error;
8416 }
8417 }
8418
8419 private:
8421 InputAdapterType ia;
8422
8424 const bool ignore_comments = false;
8425
8427 char_int_type current = std::char_traits<char_type>::eof();
8428
8430 bool next_unget = false;
8431
8433 position_t position{};
8434
8436 std::vector<char_type> token_string{};
8437
8439 string_t token_buffer{};
8440
8442 const char* error_message = "";
8443
8444 // number values
8445 number_integer_t value_integer = 0;
8446 number_unsigned_t value_unsigned = 0;
8447 number_float_t value_float = 0;
8448
8450 const char_int_type decimal_point_char = '.';
8451 };
8452 } // namespace detail
8453} // namespace nlohmann
8454
8455// #include <nlohmann/detail/macro_scope.hpp>
8456
8457// #include <nlohmann/detail/meta/is_sax.hpp>
8458
8459
8460#include <cstdint> // size_t
8461#include <utility> // declval
8462#include <string> // string
8463
8464// #include <nlohmann/detail/meta/detected.hpp>
8465
8466// #include <nlohmann/detail/meta/type_traits.hpp>
8467
8468
8469namespace nlohmann
8470{
8471 namespace detail
8472 {
8473 template<typename T>
8474 using null_function_t = decltype(std::declval<T&>().null());
8475
8476 template<typename T>
8478 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8479
8480 template<typename T, typename Integer>
8482 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8483
8484 template<typename T, typename Unsigned>
8486 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8487
8488 template<typename T, typename Float, typename String>
8489 using number_float_function_t = decltype(std::declval<T&>().number_float(
8490 std::declval<Float>(), std::declval<const String&>()));
8491
8492 template<typename T, typename String>
8494 decltype(std::declval<T&>().string(std::declval<String&>()));
8495
8496 template<typename T, typename Binary>
8498 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8499
8500 template<typename T>
8502 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8503
8504 template<typename T, typename String>
8506 decltype(std::declval<T&>().key(std::declval<String&>()));
8507
8508 template<typename T>
8509 using end_object_function_t = decltype(std::declval<T&>().end_object());
8510
8511 template<typename T>
8513 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8514
8515 template<typename T>
8516 using end_array_function_t = decltype(std::declval<T&>().end_array());
8517
8518 template<typename T, typename Exception>
8519 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8520 std::declval<std::size_t>(), std::declval<const std::string&>(),
8521 std::declval<const Exception&>()));
8522
8523 template<typename SAX, typename BasicJsonType>
8524 struct is_sax
8525 {
8526 private:
8528 "BasicJsonType must be of type basic_json<...>");
8529
8530 using number_integer_t = typename BasicJsonType::number_integer_t;
8531 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8532 using number_float_t = typename BasicJsonType::number_float_t;
8533 using string_t = typename BasicJsonType::string_t;
8534 using binary_t = typename BasicJsonType::binary_t;
8535 using exception_t = typename BasicJsonType::exception;
8536
8537 public:
8538 static constexpr bool value =
8552 };
8553
8554 template<typename SAX, typename BasicJsonType>
8556 {
8557 private:
8559 "BasicJsonType must be of type basic_json<...>");
8560
8561 using number_integer_t = typename BasicJsonType::number_integer_t;
8562 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8563 using number_float_t = typename BasicJsonType::number_float_t;
8564 using string_t = typename BasicJsonType::string_t;
8565 using binary_t = typename BasicJsonType::binary_t;
8566 using exception_t = typename BasicJsonType::exception;
8567
8568 public:
8570 "Missing/invalid function: bool null()");
8572 "Missing/invalid function: bool boolean(bool)");
8574 "Missing/invalid function: bool boolean(bool)");
8575 static_assert(
8577 number_integer_t>::value,
8578 "Missing/invalid function: bool number_integer(number_integer_t)");
8579 static_assert(
8581 number_unsigned_t>::value,
8582 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8583 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8584 number_float_t, string_t>::value,
8585 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8586 static_assert(
8588 "Missing/invalid function: bool string(string_t&)");
8589 static_assert(
8591 "Missing/invalid function: bool binary(binary_t&)");
8593 "Missing/invalid function: bool start_object(std::size_t)");
8595 "Missing/invalid function: bool key(string_t&)");
8597 "Missing/invalid function: bool end_object()");
8599 "Missing/invalid function: bool start_array(std::size_t)");
8601 "Missing/invalid function: bool end_array()");
8602 static_assert(
8604 "Missing/invalid function: bool parse_error(std::size_t, const "
8605 "std::string&, const exception&)");
8606 };
8607 } // namespace detail
8608} // namespace nlohmann
8609
8610// #include <nlohmann/detail/meta/type_traits.hpp>
8611
8612// #include <nlohmann/detail/string_concat.hpp>
8613
8614// #include <nlohmann/detail/value_t.hpp>
8615
8616
8617namespace nlohmann
8618{
8619 namespace detail
8620 {
8621
8624 {
8625 error,
8626 ignore,
8627 store
8628 };
8629
8637 static inline bool little_endianness(int num = 1) noexcept
8638 {
8639 return *reinterpret_cast<char*>(&num) == 1;
8640 }
8641
8642
8644 // binary reader //
8646
8650 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8652 {
8653 using number_integer_t = typename BasicJsonType::number_integer_t;
8654 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8655 using number_float_t = typename BasicJsonType::number_float_t;
8656 using string_t = typename BasicJsonType::string_t;
8657 using binary_t = typename BasicJsonType::binary_t;
8658 using json_sax_t = SAX;
8659 using char_type = typename InputAdapterType::char_type;
8660 using char_int_type = typename std::char_traits<char_type>::int_type;
8661
8662 public:
8668 explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
8669 {
8671 }
8672
8673 // make class move-only
8675 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8677 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8678 ~binary_reader() = default;
8679
8689 bool sax_parse(const input_format_t format,
8690 json_sax_t* sax_,
8691 const bool strict = true,
8692 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8693 {
8694 sax = sax_;
8695 bool result = false;
8696
8697 switch (format)
8698 {
8700 result = parse_bson_internal();
8701 break;
8702
8704 result = parse_cbor_internal(true, tag_handler);
8705 break;
8706
8708 result = parse_msgpack_internal();
8709 break;
8710
8713 result = parse_ubjson_internal();
8714 break;
8715
8716 case input_format_t::json: // LCOV_EXCL_LINE
8717 default: // LCOV_EXCL_LINE
8718 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8719 }
8720
8721 // strict mode: next byte must be EOF
8722 if (result && strict)
8723 {
8724 if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
8725 {
8726 get_ignore_noop();
8727 }
8728 else
8729 {
8730 get();
8731 }
8732
8733 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8734 {
8735 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
8736 exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
8737 }
8738 }
8739
8740 return result;
8741 }
8742
8743 private:
8745 // BSON //
8747
8752 bool parse_bson_internal()
8753 {
8754 std::int32_t document_size{};
8755 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8756
8757 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
8758 {
8759 return false;
8760 }
8761
8762 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8763 {
8764 return false;
8765 }
8766
8767 return sax->end_object();
8768 }
8769
8777 bool get_bson_cstr(string_t& result)
8778 {
8779 auto out = std::back_inserter(result);
8780 while (true)
8781 {
8782 get();
8783 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8784 {
8785 return false;
8786 }
8787 if (current == 0x00)
8788 {
8789 return true;
8790 }
8791 *out++ = static_cast<typename string_t::value_type>(current);
8792 }
8793 }
8794
8806 template<typename NumberType>
8807 bool get_bson_string(const NumberType len, string_t& result)
8808 {
8809 if (JSON_HEDLEY_UNLIKELY(len < 1))
8810 {
8811 auto last_token = get_token_string();
8812 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8813 exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
8814 }
8815
8816 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8817 }
8818
8828 template<typename NumberType>
8829 bool get_bson_binary(const NumberType len, binary_t& result)
8830 {
8831 if (JSON_HEDLEY_UNLIKELY(len < 0))
8832 {
8833 auto last_token = get_token_string();
8834 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8835 exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
8836 }
8837
8838 // All BSON binary values have a subtype
8839 std::uint8_t subtype{};
8840 get_number<std::uint8_t>(input_format_t::bson, subtype);
8841 result.set_subtype(subtype);
8842
8843 return get_binary(input_format_t::bson, len, result);
8844 }
8845
8856 bool parse_bson_element_internal(const char_int_type element_type,
8857 const std::size_t element_type_parse_position)
8858 {
8859 switch (element_type)
8860 {
8861 case 0x01: // double
8862 {
8863 double number{};
8864 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8865 }
8866
8867 case 0x02: // string
8868 {
8869 std::int32_t len{};
8870 string_t value;
8871 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8872 }
8873
8874 case 0x03: // object
8875 {
8876 return parse_bson_internal();
8877 }
8878
8879 case 0x04: // array
8880 {
8881 return parse_bson_array();
8882 }
8883
8884 case 0x05: // binary
8885 {
8886 std::int32_t len{};
8887 binary_t value;
8888 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8889 }
8890
8891 case 0x08: // boolean
8892 {
8893 return sax->boolean(get() != 0);
8894 }
8895
8896 case 0x0A: // null
8897 {
8898 return sax->null();
8899 }
8900
8901 case 0x10: // int32
8902 {
8903 std::int32_t value{};
8904 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8905 }
8906
8907 case 0x12: // int64
8908 {
8909 std::int64_t value{};
8910 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8911 }
8912
8913 default: // anything else not supported (yet)
8914 {
8915 std::array<char, 3> cr{ {} };
8916 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8917 std::string cr_str{ cr.data() };
8918 return sax->parse_error(element_type_parse_position, cr_str,
8919 parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
8920 }
8921 }
8922 }
8923
8936 bool parse_bson_element_list(const bool is_array)
8937 {
8938 string_t key;
8939
8940 while (auto element_type = get())
8941 {
8942 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8943 {
8944 return false;
8945 }
8946
8947 const std::size_t element_type_parse_position = chars_read;
8948 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8949 {
8950 return false;
8951 }
8952
8953 if (!is_array && !sax->key(key))
8954 {
8955 return false;
8956 }
8957
8958 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8959 {
8960 return false;
8961 }
8962
8963 // get_bson_cstr only appends
8964 key.clear();
8965 }
8966
8967 return true;
8968 }
8969
8974 bool parse_bson_array()
8975 {
8976 std::int32_t document_size{};
8977 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8978
8979 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
8980 {
8981 return false;
8982 }
8983
8984 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8985 {
8986 return false;
8987 }
8988
8989 return sax->end_array();
8990 }
8991
8993 // CBOR //
8995
9004 bool parse_cbor_internal(const bool get_char,
9005 const cbor_tag_handler_t tag_handler)
9006 {
9007 switch (get_char ? get() : current)
9008 {
9009 // EOF
9010 case std::char_traits<char_type>::eof():
9011 return unexpect_eof(input_format_t::cbor, "value");
9012
9013 // Integer 0x00..0x17 (0..23)
9014 case 0x00:
9015 case 0x01:
9016 case 0x02:
9017 case 0x03:
9018 case 0x04:
9019 case 0x05:
9020 case 0x06:
9021 case 0x07:
9022 case 0x08:
9023 case 0x09:
9024 case 0x0A:
9025 case 0x0B:
9026 case 0x0C:
9027 case 0x0D:
9028 case 0x0E:
9029 case 0x0F:
9030 case 0x10:
9031 case 0x11:
9032 case 0x12:
9033 case 0x13:
9034 case 0x14:
9035 case 0x15:
9036 case 0x16:
9037 case 0x17:
9038 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9039
9040 case 0x18: // Unsigned integer (one-byte uint8_t follows)
9041 {
9042 std::uint8_t number{};
9043 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9044 }
9045
9046 case 0x19: // Unsigned integer (two-byte uint16_t follows)
9047 {
9048 std::uint16_t number{};
9049 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9050 }
9051
9052 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9053 {
9054 std::uint32_t number{};
9055 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9056 }
9057
9058 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9059 {
9060 std::uint64_t number{};
9061 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9062 }
9063
9064 // Negative integer -1-0x00..-1-0x17 (-1..-24)
9065 case 0x20:
9066 case 0x21:
9067 case 0x22:
9068 case 0x23:
9069 case 0x24:
9070 case 0x25:
9071 case 0x26:
9072 case 0x27:
9073 case 0x28:
9074 case 0x29:
9075 case 0x2A:
9076 case 0x2B:
9077 case 0x2C:
9078 case 0x2D:
9079 case 0x2E:
9080 case 0x2F:
9081 case 0x30:
9082 case 0x31:
9083 case 0x32:
9084 case 0x33:
9085 case 0x34:
9086 case 0x35:
9087 case 0x36:
9088 case 0x37:
9089 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9090
9091 case 0x38: // Negative integer (one-byte uint8_t follows)
9092 {
9093 std::uint8_t number{};
9094 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9095 }
9096
9097 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9098 {
9099 std::uint16_t number{};
9100 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9101 }
9102
9103 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9104 {
9105 std::uint32_t number{};
9106 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9107 }
9108
9109 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9110 {
9111 std::uint64_t number{};
9112 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9113 - static_cast<number_integer_t>(number));
9114 }
9115
9116 // Binary data (0x00..0x17 bytes follow)
9117 case 0x40:
9118 case 0x41:
9119 case 0x42:
9120 case 0x43:
9121 case 0x44:
9122 case 0x45:
9123 case 0x46:
9124 case 0x47:
9125 case 0x48:
9126 case 0x49:
9127 case 0x4A:
9128 case 0x4B:
9129 case 0x4C:
9130 case 0x4D:
9131 case 0x4E:
9132 case 0x4F:
9133 case 0x50:
9134 case 0x51:
9135 case 0x52:
9136 case 0x53:
9137 case 0x54:
9138 case 0x55:
9139 case 0x56:
9140 case 0x57:
9141 case 0x58: // Binary data (one-byte uint8_t for n follows)
9142 case 0x59: // Binary data (two-byte uint16_t for n follow)
9143 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9144 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9145 case 0x5F: // Binary data (indefinite length)
9146 {
9147 binary_t b;
9148 return get_cbor_binary(b) && sax->binary(b);
9149 }
9150
9151 // UTF-8 string (0x00..0x17 bytes follow)
9152 case 0x60:
9153 case 0x61:
9154 case 0x62:
9155 case 0x63:
9156 case 0x64:
9157 case 0x65:
9158 case 0x66:
9159 case 0x67:
9160 case 0x68:
9161 case 0x69:
9162 case 0x6A:
9163 case 0x6B:
9164 case 0x6C:
9165 case 0x6D:
9166 case 0x6E:
9167 case 0x6F:
9168 case 0x70:
9169 case 0x71:
9170 case 0x72:
9171 case 0x73:
9172 case 0x74:
9173 case 0x75:
9174 case 0x76:
9175 case 0x77:
9176 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9177 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9178 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9179 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9180 case 0x7F: // UTF-8 string (indefinite length)
9181 {
9182 string_t s;
9183 return get_cbor_string(s) && sax->string(s);
9184 }
9185
9186 // array (0x00..0x17 data items follow)
9187 case 0x80:
9188 case 0x81:
9189 case 0x82:
9190 case 0x83:
9191 case 0x84:
9192 case 0x85:
9193 case 0x86:
9194 case 0x87:
9195 case 0x88:
9196 case 0x89:
9197 case 0x8A:
9198 case 0x8B:
9199 case 0x8C:
9200 case 0x8D:
9201 case 0x8E:
9202 case 0x8F:
9203 case 0x90:
9204 case 0x91:
9205 case 0x92:
9206 case 0x93:
9207 case 0x94:
9208 case 0x95:
9209 case 0x96:
9210 case 0x97:
9211 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9212
9213 case 0x98: // array (one-byte uint8_t for n follows)
9214 {
9215 std::uint8_t len{};
9216 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9217 }
9218
9219 case 0x99: // array (two-byte uint16_t for n follow)
9220 {
9221 std::uint16_t len{};
9222 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9223 }
9224
9225 case 0x9A: // array (four-byte uint32_t for n follow)
9226 {
9227 std::uint32_t len{};
9228 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9229 }
9230
9231 case 0x9B: // array (eight-byte uint64_t for n follow)
9232 {
9233 std::uint64_t len{};
9234 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9235 }
9236
9237 case 0x9F: // array (indefinite length)
9238 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9239
9240 // map (0x00..0x17 pairs of data items follow)
9241 case 0xA0:
9242 case 0xA1:
9243 case 0xA2:
9244 case 0xA3:
9245 case 0xA4:
9246 case 0xA5:
9247 case 0xA6:
9248 case 0xA7:
9249 case 0xA8:
9250 case 0xA9:
9251 case 0xAA:
9252 case 0xAB:
9253 case 0xAC:
9254 case 0xAD:
9255 case 0xAE:
9256 case 0xAF:
9257 case 0xB0:
9258 case 0xB1:
9259 case 0xB2:
9260 case 0xB3:
9261 case 0xB4:
9262 case 0xB5:
9263 case 0xB6:
9264 case 0xB7:
9265 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9266
9267 case 0xB8: // map (one-byte uint8_t for n follows)
9268 {
9269 std::uint8_t len{};
9270 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9271 }
9272
9273 case 0xB9: // map (two-byte uint16_t for n follow)
9274 {
9275 std::uint16_t len{};
9276 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9277 }
9278
9279 case 0xBA: // map (four-byte uint32_t for n follow)
9280 {
9281 std::uint32_t len{};
9282 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9283 }
9284
9285 case 0xBB: // map (eight-byte uint64_t for n follow)
9286 {
9287 std::uint64_t len{};
9288 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9289 }
9290
9291 case 0xBF: // map (indefinite length)
9292 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9293
9294 case 0xC6: // tagged item
9295 case 0xC7:
9296 case 0xC8:
9297 case 0xC9:
9298 case 0xCA:
9299 case 0xCB:
9300 case 0xCC:
9301 case 0xCD:
9302 case 0xCE:
9303 case 0xCF:
9304 case 0xD0:
9305 case 0xD1:
9306 case 0xD2:
9307 case 0xD3:
9308 case 0xD4:
9309 case 0xD8: // tagged item (1 bytes follow)
9310 case 0xD9: // tagged item (2 bytes follow)
9311 case 0xDA: // tagged item (4 bytes follow)
9312 case 0xDB: // tagged item (8 bytes follow)
9313 {
9314 switch (tag_handler)
9315 {
9317 {
9318 auto last_token = get_token_string();
9319 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9320 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9321 }
9322
9324 {
9325 // ignore binary subtype
9326 switch (current)
9327 {
9328 case 0xD8:
9329 {
9330 std::uint8_t subtype_to_ignore{};
9331 get_number(input_format_t::cbor, subtype_to_ignore);
9332 break;
9333 }
9334 case 0xD9:
9335 {
9336 std::uint16_t subtype_to_ignore{};
9337 get_number(input_format_t::cbor, subtype_to_ignore);
9338 break;
9339 }
9340 case 0xDA:
9341 {
9342 std::uint32_t subtype_to_ignore{};
9343 get_number(input_format_t::cbor, subtype_to_ignore);
9344 break;
9345 }
9346 case 0xDB:
9347 {
9348 std::uint64_t subtype_to_ignore{};
9349 get_number(input_format_t::cbor, subtype_to_ignore);
9350 break;
9351 }
9352 default:
9353 break;
9354 }
9355 return parse_cbor_internal(true, tag_handler);
9356 }
9357
9359 {
9360 binary_t b;
9361 // use binary subtype and store in binary container
9362 switch (current)
9363 {
9364 case 0xD8:
9365 {
9366 std::uint8_t subtype{};
9367 get_number(input_format_t::cbor, subtype);
9368 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9369 break;
9370 }
9371 case 0xD9:
9372 {
9373 std::uint16_t subtype{};
9374 get_number(input_format_t::cbor, subtype);
9375 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9376 break;
9377 }
9378 case 0xDA:
9379 {
9380 std::uint32_t subtype{};
9381 get_number(input_format_t::cbor, subtype);
9382 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9383 break;
9384 }
9385 case 0xDB:
9386 {
9387 std::uint64_t subtype{};
9388 get_number(input_format_t::cbor, subtype);
9389 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9390 break;
9391 }
9392 default:
9393 return parse_cbor_internal(true, tag_handler);
9394 }
9395 get();
9396 return get_cbor_binary(b) && sax->binary(b);
9397 }
9398
9399 default: // LCOV_EXCL_LINE
9400 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9401 return false; // LCOV_EXCL_LINE
9402 }
9403 }
9404
9405 case 0xF4: // false
9406 return sax->boolean(false);
9407
9408 case 0xF5: // true
9409 return sax->boolean(true);
9410
9411 case 0xF6: // null
9412 return sax->null();
9413
9414 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9415 {
9416 const auto byte1_raw = get();
9417 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9418 {
9419 return false;
9420 }
9421 const auto byte2_raw = get();
9422 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9423 {
9424 return false;
9425 }
9426
9427 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9428 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9429
9430 // code from RFC 7049, Appendix D, Figure 3:
9431 // As half-precision floating-point numbers were only added
9432 // to IEEE 754 in 2008, today's programming platforms often
9433 // still only have limited support for them. It is very
9434 // easy to include at least decoding support for them even
9435 // without such support. An example of a small decoder for
9436 // half-precision floating-point numbers in the C language
9437 // is shown in Fig. 3.
9438 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9439 const double val = [&half]
9440 {
9441 const int exp = (half >> 10u) & 0x1Fu;
9442 const unsigned int mant = half & 0x3FFu;
9443 JSON_ASSERT(0 <= exp && exp <= 32);
9444 JSON_ASSERT(mant <= 1024);
9445 switch (exp)
9446 {
9447 case 0:
9448 return std::ldexp(mant, -24);
9449 case 31:
9450 return (mant == 0)
9451 ? std::numeric_limits<double>::infinity()
9452 : std::numeric_limits<double>::quiet_NaN();
9453 default:
9454 return std::ldexp(mant + 1024, exp - 25);
9455 }
9456 }();
9457 return sax->number_float((half & 0x8000u) != 0
9458 ? static_cast<number_float_t>(-val)
9459 : static_cast<number_float_t>(val), "");
9460 }
9461
9462 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9463 {
9464 float number{};
9465 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9466 }
9467
9468 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9469 {
9470 double number{};
9471 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9472 }
9473
9474 default: // anything else (0xFF is handled inside the other types)
9475 {
9476 auto last_token = get_token_string();
9477 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9478 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9479 }
9480 }
9481 }
9482
9494 bool get_cbor_string(string_t& result)
9495 {
9496 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9497 {
9498 return false;
9499 }
9500
9501 switch (current)
9502 {
9503 // UTF-8 string (0x00..0x17 bytes follow)
9504 case 0x60:
9505 case 0x61:
9506 case 0x62:
9507 case 0x63:
9508 case 0x64:
9509 case 0x65:
9510 case 0x66:
9511 case 0x67:
9512 case 0x68:
9513 case 0x69:
9514 case 0x6A:
9515 case 0x6B:
9516 case 0x6C:
9517 case 0x6D:
9518 case 0x6E:
9519 case 0x6F:
9520 case 0x70:
9521 case 0x71:
9522 case 0x72:
9523 case 0x73:
9524 case 0x74:
9525 case 0x75:
9526 case 0x76:
9527 case 0x77:
9528 {
9529 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9530 }
9531
9532 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9533 {
9534 std::uint8_t len{};
9535 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9536 }
9537
9538 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9539 {
9540 std::uint16_t len{};
9541 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9542 }
9543
9544 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9545 {
9546 std::uint32_t len{};
9547 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9548 }
9549
9550 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9551 {
9552 std::uint64_t len{};
9553 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9554 }
9555
9556 case 0x7F: // UTF-8 string (indefinite length)
9557 {
9558 while (get() != 0xFF)
9559 {
9560 string_t chunk;
9561 if (!get_cbor_string(chunk))
9562 {
9563 return false;
9564 }
9565 result.append(chunk);
9566 }
9567 return true;
9568 }
9569
9570 default:
9571 {
9572 auto last_token = get_token_string();
9573 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9574 exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
9575 }
9576 }
9577 }
9578
9590 bool get_cbor_binary(binary_t& result)
9591 {
9592 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9593 {
9594 return false;
9595 }
9596
9597 switch (current)
9598 {
9599 // Binary data (0x00..0x17 bytes follow)
9600 case 0x40:
9601 case 0x41:
9602 case 0x42:
9603 case 0x43:
9604 case 0x44:
9605 case 0x45:
9606 case 0x46:
9607 case 0x47:
9608 case 0x48:
9609 case 0x49:
9610 case 0x4A:
9611 case 0x4B:
9612 case 0x4C:
9613 case 0x4D:
9614 case 0x4E:
9615 case 0x4F:
9616 case 0x50:
9617 case 0x51:
9618 case 0x52:
9619 case 0x53:
9620 case 0x54:
9621 case 0x55:
9622 case 0x56:
9623 case 0x57:
9624 {
9625 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9626 }
9627
9628 case 0x58: // Binary data (one-byte uint8_t for n follows)
9629 {
9630 std::uint8_t len{};
9631 return get_number(input_format_t::cbor, len) &&
9632 get_binary(input_format_t::cbor, len, result);
9633 }
9634
9635 case 0x59: // Binary data (two-byte uint16_t for n follow)
9636 {
9637 std::uint16_t len{};
9638 return get_number(input_format_t::cbor, len) &&
9639 get_binary(input_format_t::cbor, len, result);
9640 }
9641
9642 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9643 {
9644 std::uint32_t len{};
9645 return get_number(input_format_t::cbor, len) &&
9646 get_binary(input_format_t::cbor, len, result);
9647 }
9648
9649 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9650 {
9651 std::uint64_t len{};
9652 return get_number(input_format_t::cbor, len) &&
9653 get_binary(input_format_t::cbor, len, result);
9654 }
9655
9656 case 0x5F: // Binary data (indefinite length)
9657 {
9658 while (get() != 0xFF)
9659 {
9660 binary_t chunk;
9661 if (!get_cbor_binary(chunk))
9662 {
9663 return false;
9664 }
9665 result.insert(result.end(), chunk.begin(), chunk.end());
9666 }
9667 return true;
9668 }
9669
9670 default:
9671 {
9672 auto last_token = get_token_string();
9673 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9674 exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
9675 }
9676 }
9677 }
9678
9685 bool get_cbor_array(const std::size_t len,
9686 const cbor_tag_handler_t tag_handler)
9687 {
9688 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9689 {
9690 return false;
9691 }
9692
9693 if (len != static_cast<std::size_t>(-1))
9694 {
9695 for (std::size_t i = 0; i < len; ++i)
9696 {
9697 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9698 {
9699 return false;
9700 }
9701 }
9702 }
9703 else
9704 {
9705 while (get() != 0xFF)
9706 {
9707 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9708 {
9709 return false;
9710 }
9711 }
9712 }
9713
9714 return sax->end_array();
9715 }
9716
9723 bool get_cbor_object(const std::size_t len,
9724 const cbor_tag_handler_t tag_handler)
9725 {
9726 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9727 {
9728 return false;
9729 }
9730
9731 if (len != 0)
9732 {
9733 string_t key;
9734 if (len != static_cast<std::size_t>(-1))
9735 {
9736 for (std::size_t i = 0; i < len; ++i)
9737 {
9738 get();
9739 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9740 {
9741 return false;
9742 }
9743
9744 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9745 {
9746 return false;
9747 }
9748 key.clear();
9749 }
9750 }
9751 else
9752 {
9753 while (get() != 0xFF)
9754 {
9755 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9756 {
9757 return false;
9758 }
9759
9760 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9761 {
9762 return false;
9763 }
9764 key.clear();
9765 }
9766 }
9767 }
9768
9769 return sax->end_object();
9770 }
9771
9773 // MsgPack //
9775
9779 bool parse_msgpack_internal()
9780 {
9781 switch (get())
9782 {
9783 // EOF
9784 case std::char_traits<char_type>::eof():
9785 return unexpect_eof(input_format_t::msgpack, "value");
9786
9787 // positive fixint
9788 case 0x00:
9789 case 0x01:
9790 case 0x02:
9791 case 0x03:
9792 case 0x04:
9793 case 0x05:
9794 case 0x06:
9795 case 0x07:
9796 case 0x08:
9797 case 0x09:
9798 case 0x0A:
9799 case 0x0B:
9800 case 0x0C:
9801 case 0x0D:
9802 case 0x0E:
9803 case 0x0F:
9804 case 0x10:
9805 case 0x11:
9806 case 0x12:
9807 case 0x13:
9808 case 0x14:
9809 case 0x15:
9810 case 0x16:
9811 case 0x17:
9812 case 0x18:
9813 case 0x19:
9814 case 0x1A:
9815 case 0x1B:
9816 case 0x1C:
9817 case 0x1D:
9818 case 0x1E:
9819 case 0x1F:
9820 case 0x20:
9821 case 0x21:
9822 case 0x22:
9823 case 0x23:
9824 case 0x24:
9825 case 0x25:
9826 case 0x26:
9827 case 0x27:
9828 case 0x28:
9829 case 0x29:
9830 case 0x2A:
9831 case 0x2B:
9832 case 0x2C:
9833 case 0x2D:
9834 case 0x2E:
9835 case 0x2F:
9836 case 0x30:
9837 case 0x31:
9838 case 0x32:
9839 case 0x33:
9840 case 0x34:
9841 case 0x35:
9842 case 0x36:
9843 case 0x37:
9844 case 0x38:
9845 case 0x39:
9846 case 0x3A:
9847 case 0x3B:
9848 case 0x3C:
9849 case 0x3D:
9850 case 0x3E:
9851 case 0x3F:
9852 case 0x40:
9853 case 0x41:
9854 case 0x42:
9855 case 0x43:
9856 case 0x44:
9857 case 0x45:
9858 case 0x46:
9859 case 0x47:
9860 case 0x48:
9861 case 0x49:
9862 case 0x4A:
9863 case 0x4B:
9864 case 0x4C:
9865 case 0x4D:
9866 case 0x4E:
9867 case 0x4F:
9868 case 0x50:
9869 case 0x51:
9870 case 0x52:
9871 case 0x53:
9872 case 0x54:
9873 case 0x55:
9874 case 0x56:
9875 case 0x57:
9876 case 0x58:
9877 case 0x59:
9878 case 0x5A:
9879 case 0x5B:
9880 case 0x5C:
9881 case 0x5D:
9882 case 0x5E:
9883 case 0x5F:
9884 case 0x60:
9885 case 0x61:
9886 case 0x62:
9887 case 0x63:
9888 case 0x64:
9889 case 0x65:
9890 case 0x66:
9891 case 0x67:
9892 case 0x68:
9893 case 0x69:
9894 case 0x6A:
9895 case 0x6B:
9896 case 0x6C:
9897 case 0x6D:
9898 case 0x6E:
9899 case 0x6F:
9900 case 0x70:
9901 case 0x71:
9902 case 0x72:
9903 case 0x73:
9904 case 0x74:
9905 case 0x75:
9906 case 0x76:
9907 case 0x77:
9908 case 0x78:
9909 case 0x79:
9910 case 0x7A:
9911 case 0x7B:
9912 case 0x7C:
9913 case 0x7D:
9914 case 0x7E:
9915 case 0x7F:
9916 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9917
9918 // fixmap
9919 case 0x80:
9920 case 0x81:
9921 case 0x82:
9922 case 0x83:
9923 case 0x84:
9924 case 0x85:
9925 case 0x86:
9926 case 0x87:
9927 case 0x88:
9928 case 0x89:
9929 case 0x8A:
9930 case 0x8B:
9931 case 0x8C:
9932 case 0x8D:
9933 case 0x8E:
9934 case 0x8F:
9935 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9936
9937 // fixarray
9938 case 0x90:
9939 case 0x91:
9940 case 0x92:
9941 case 0x93:
9942 case 0x94:
9943 case 0x95:
9944 case 0x96:
9945 case 0x97:
9946 case 0x98:
9947 case 0x99:
9948 case 0x9A:
9949 case 0x9B:
9950 case 0x9C:
9951 case 0x9D:
9952 case 0x9E:
9953 case 0x9F:
9954 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9955
9956 // fixstr
9957 case 0xA0:
9958 case 0xA1:
9959 case 0xA2:
9960 case 0xA3:
9961 case 0xA4:
9962 case 0xA5:
9963 case 0xA6:
9964 case 0xA7:
9965 case 0xA8:
9966 case 0xA9:
9967 case 0xAA:
9968 case 0xAB:
9969 case 0xAC:
9970 case 0xAD:
9971 case 0xAE:
9972 case 0xAF:
9973 case 0xB0:
9974 case 0xB1:
9975 case 0xB2:
9976 case 0xB3:
9977 case 0xB4:
9978 case 0xB5:
9979 case 0xB6:
9980 case 0xB7:
9981 case 0xB8:
9982 case 0xB9:
9983 case 0xBA:
9984 case 0xBB:
9985 case 0xBC:
9986 case 0xBD:
9987 case 0xBE:
9988 case 0xBF:
9989 case 0xD9: // str 8
9990 case 0xDA: // str 16
9991 case 0xDB: // str 32
9992 {
9993 string_t s;
9994 return get_msgpack_string(s) && sax->string(s);
9995 }
9996
9997 case 0xC0: // nil
9998 return sax->null();
9999
10000 case 0xC2: // false
10001 return sax->boolean(false);
10002
10003 case 0xC3: // true
10004 return sax->boolean(true);
10005
10006 case 0xC4: // bin 8
10007 case 0xC5: // bin 16
10008 case 0xC6: // bin 32
10009 case 0xC7: // ext 8
10010 case 0xC8: // ext 16
10011 case 0xC9: // ext 32
10012 case 0xD4: // fixext 1
10013 case 0xD5: // fixext 2
10014 case 0xD6: // fixext 4
10015 case 0xD7: // fixext 8
10016 case 0xD8: // fixext 16
10017 {
10018 binary_t b;
10019 return get_msgpack_binary(b) && sax->binary(b);
10020 }
10021
10022 case 0xCA: // float 32
10023 {
10024 float number{};
10025 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10026 }
10027
10028 case 0xCB: // float 64
10029 {
10030 double number{};
10031 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10032 }
10033
10034 case 0xCC: // uint 8
10035 {
10036 std::uint8_t number{};
10037 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10038 }
10039
10040 case 0xCD: // uint 16
10041 {
10042 std::uint16_t number{};
10043 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10044 }
10045
10046 case 0xCE: // uint 32
10047 {
10048 std::uint32_t number{};
10049 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10050 }
10051
10052 case 0xCF: // uint 64
10053 {
10054 std::uint64_t number{};
10055 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10056 }
10057
10058 case 0xD0: // int 8
10059 {
10060 std::int8_t number{};
10061 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10062 }
10063
10064 case 0xD1: // int 16
10065 {
10066 std::int16_t number{};
10067 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10068 }
10069
10070 case 0xD2: // int 32
10071 {
10072 std::int32_t number{};
10073 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10074 }
10075
10076 case 0xD3: // int 64
10077 {
10078 std::int64_t number{};
10079 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10080 }
10081
10082 case 0xDC: // array 16
10083 {
10084 std::uint16_t len{};
10085 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10086 }
10087
10088 case 0xDD: // array 32
10089 {
10090 std::uint32_t len{};
10091 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10092 }
10093
10094 case 0xDE: // map 16
10095 {
10096 std::uint16_t len{};
10097 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10098 }
10099
10100 case 0xDF: // map 32
10101 {
10102 std::uint32_t len{};
10103 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10104 }
10105
10106 // negative fixint
10107 case 0xE0:
10108 case 0xE1:
10109 case 0xE2:
10110 case 0xE3:
10111 case 0xE4:
10112 case 0xE5:
10113 case 0xE6:
10114 case 0xE7:
10115 case 0xE8:
10116 case 0xE9:
10117 case 0xEA:
10118 case 0xEB:
10119 case 0xEC:
10120 case 0xED:
10121 case 0xEE:
10122 case 0xEF:
10123 case 0xF0:
10124 case 0xF1:
10125 case 0xF2:
10126 case 0xF3:
10127 case 0xF4:
10128 case 0xF5:
10129 case 0xF6:
10130 case 0xF7:
10131 case 0xF8:
10132 case 0xF9:
10133 case 0xFA:
10134 case 0xFB:
10135 case 0xFC:
10136 case 0xFD:
10137 case 0xFE:
10138 case 0xFF:
10139 return sax->number_integer(static_cast<std::int8_t>(current));
10140
10141 default: // anything else
10142 {
10143 auto last_token = get_token_string();
10144 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10145 exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10146 }
10147 }
10148 }
10149
10160 bool get_msgpack_string(string_t& result)
10161 {
10162 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10163 {
10164 return false;
10165 }
10166
10167 switch (current)
10168 {
10169 // fixstr
10170 case 0xA0:
10171 case 0xA1:
10172 case 0xA2:
10173 case 0xA3:
10174 case 0xA4:
10175 case 0xA5:
10176 case 0xA6:
10177 case 0xA7:
10178 case 0xA8:
10179 case 0xA9:
10180 case 0xAA:
10181 case 0xAB:
10182 case 0xAC:
10183 case 0xAD:
10184 case 0xAE:
10185 case 0xAF:
10186 case 0xB0:
10187 case 0xB1:
10188 case 0xB2:
10189 case 0xB3:
10190 case 0xB4:
10191 case 0xB5:
10192 case 0xB6:
10193 case 0xB7:
10194 case 0xB8:
10195 case 0xB9:
10196 case 0xBA:
10197 case 0xBB:
10198 case 0xBC:
10199 case 0xBD:
10200 case 0xBE:
10201 case 0xBF:
10202 {
10203 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10204 }
10205
10206 case 0xD9: // str 8
10207 {
10208 std::uint8_t len{};
10209 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10210 }
10211
10212 case 0xDA: // str 16
10213 {
10214 std::uint16_t len{};
10215 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10216 }
10217
10218 case 0xDB: // str 32
10219 {
10220 std::uint32_t len{};
10221 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10222 }
10223
10224 default:
10225 {
10226 auto last_token = get_token_string();
10227 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10228 exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10229 }
10230 }
10231 }
10232
10243 bool get_msgpack_binary(binary_t& result)
10244 {
10245 // helper function to set the subtype
10246 auto assign_and_return_true = [&result](std::int8_t subtype)
10247 {
10248 result.set_subtype(static_cast<std::uint8_t>(subtype));
10249 return true;
10250 };
10251
10252 switch (current)
10253 {
10254 case 0xC4: // bin 8
10255 {
10256 std::uint8_t len{};
10257 return get_number(input_format_t::msgpack, len) &&
10258 get_binary(input_format_t::msgpack, len, result);
10259 }
10260
10261 case 0xC5: // bin 16
10262 {
10263 std::uint16_t len{};
10264 return get_number(input_format_t::msgpack, len) &&
10265 get_binary(input_format_t::msgpack, len, result);
10266 }
10267
10268 case 0xC6: // bin 32
10269 {
10270 std::uint32_t len{};
10271 return get_number(input_format_t::msgpack, len) &&
10272 get_binary(input_format_t::msgpack, len, result);
10273 }
10274
10275 case 0xC7: // ext 8
10276 {
10277 std::uint8_t len{};
10278 std::int8_t subtype{};
10279 return get_number(input_format_t::msgpack, len) &&
10280 get_number(input_format_t::msgpack, subtype) &&
10281 get_binary(input_format_t::msgpack, len, result) &&
10282 assign_and_return_true(subtype);
10283 }
10284
10285 case 0xC8: // ext 16
10286 {
10287 std::uint16_t len{};
10288 std::int8_t subtype{};
10289 return get_number(input_format_t::msgpack, len) &&
10290 get_number(input_format_t::msgpack, subtype) &&
10291 get_binary(input_format_t::msgpack, len, result) &&
10292 assign_and_return_true(subtype);
10293 }
10294
10295 case 0xC9: // ext 32
10296 {
10297 std::uint32_t len{};
10298 std::int8_t subtype{};
10299 return get_number(input_format_t::msgpack, len) &&
10300 get_number(input_format_t::msgpack, subtype) &&
10301 get_binary(input_format_t::msgpack, len, result) &&
10302 assign_and_return_true(subtype);
10303 }
10304
10305 case 0xD4: // fixext 1
10306 {
10307 std::int8_t subtype{};
10308 return get_number(input_format_t::msgpack, subtype) &&
10309 get_binary(input_format_t::msgpack, 1, result) &&
10310 assign_and_return_true(subtype);
10311 }
10312
10313 case 0xD5: // fixext 2
10314 {
10315 std::int8_t subtype{};
10316 return get_number(input_format_t::msgpack, subtype) &&
10317 get_binary(input_format_t::msgpack, 2, result) &&
10318 assign_and_return_true(subtype);
10319 }
10320
10321 case 0xD6: // fixext 4
10322 {
10323 std::int8_t subtype{};
10324 return get_number(input_format_t::msgpack, subtype) &&
10325 get_binary(input_format_t::msgpack, 4, result) &&
10326 assign_and_return_true(subtype);
10327 }
10328
10329 case 0xD7: // fixext 8
10330 {
10331 std::int8_t subtype{};
10332 return get_number(input_format_t::msgpack, subtype) &&
10333 get_binary(input_format_t::msgpack, 8, result) &&
10334 assign_and_return_true(subtype);
10335 }
10336
10337 case 0xD8: // fixext 16
10338 {
10339 std::int8_t subtype{};
10340 return get_number(input_format_t::msgpack, subtype) &&
10341 get_binary(input_format_t::msgpack, 16, result) &&
10342 assign_and_return_true(subtype);
10343 }
10344
10345 default: // LCOV_EXCL_LINE
10346 return false; // LCOV_EXCL_LINE
10347 }
10348 }
10349
10354 bool get_msgpack_array(const std::size_t len)
10355 {
10356 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10357 {
10358 return false;
10359 }
10360
10361 for (std::size_t i = 0; i < len; ++i)
10362 {
10363 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10364 {
10365 return false;
10366 }
10367 }
10368
10369 return sax->end_array();
10370 }
10371
10376 bool get_msgpack_object(const std::size_t len)
10377 {
10378 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10379 {
10380 return false;
10381 }
10382
10383 string_t key;
10384 for (std::size_t i = 0; i < len; ++i)
10385 {
10386 get();
10387 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10388 {
10389 return false;
10390 }
10391
10392 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10393 {
10394 return false;
10395 }
10396 key.clear();
10397 }
10398
10399 return sax->end_object();
10400 }
10401
10403 // UBJSON //
10405
10413 bool parse_ubjson_internal(const bool get_char = true)
10414 {
10415 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10416 }
10417
10432 bool get_ubjson_string(string_t& result, const bool get_char = true)
10433 {
10434 if (get_char)
10435 {
10436 get(); // TODO(niels): may we ignore N here?
10437 }
10438
10439 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10440 {
10441 return false;
10442 }
10443
10444 switch (current)
10445 {
10446 case 'U':
10447 {
10448 std::uint8_t len{};
10449 return get_number(input_format, len) && get_string(input_format, len, result);
10450 }
10451
10452 case 'i':
10453 {
10454 std::int8_t len{};
10455 return get_number(input_format, len) && get_string(input_format, len, result);
10456 }
10457
10458 case 'I':
10459 {
10460 std::int16_t len{};
10461 return get_number(input_format, len) && get_string(input_format, len, result);
10462 }
10463
10464 case 'l':
10465 {
10466 std::int32_t len{};
10467 return get_number(input_format, len) && get_string(input_format, len, result);
10468 }
10469
10470 case 'L':
10471 {
10472 std::int64_t len{};
10473 return get_number(input_format, len) && get_string(input_format, len, result);
10474 }
10475
10476 case 'u':
10477 {
10478 if (input_format != input_format_t::bjdata)
10479 {
10480 break;
10481 }
10482 std::uint16_t len{};
10483 return get_number(input_format, len) && get_string(input_format, len, result);
10484 }
10485
10486 case 'm':
10487 {
10488 if (input_format != input_format_t::bjdata)
10489 {
10490 break;
10491 }
10492 std::uint32_t len{};
10493 return get_number(input_format, len) && get_string(input_format, len, result);
10494 }
10495
10496 case 'M':
10497 {
10498 if (input_format != input_format_t::bjdata)
10499 {
10500 break;
10501 }
10502 std::uint64_t len{};
10503 return get_number(input_format, len) && get_string(input_format, len, result);
10504 }
10505
10506 default:
10507 break;
10508 }
10509 auto last_token = get_token_string();
10510 std::string message;
10511
10512 if (input_format != input_format_t::bjdata)
10513 {
10514 message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
10515 }
10516 else
10517 {
10518 message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
10519 }
10520 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
10521 }
10522
10527 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
10528 {
10529 std::pair<std::size_t, char_int_type> size_and_type;
10530 size_t dimlen = 0;
10531 bool inside_ndarray = true;
10532
10533 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, inside_ndarray)))
10534 {
10535 return false;
10536 }
10537
10538 if (size_and_type.first != string_t::npos)
10539 {
10540 if (size_and_type.second != 0)
10541 {
10542 if (size_and_type.second != 'N')
10543 {
10544 for (std::size_t i = 0; i < size_and_type.first; ++i)
10545 {
10546 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, inside_ndarray, size_and_type.second)))
10547 {
10548 return false;
10549 }
10550 dim.push_back(dimlen);
10551 }
10552 }
10553 }
10554 else
10555 {
10556 for (std::size_t i = 0; i < size_and_type.first; ++i)
10557 {
10558 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, inside_ndarray)))
10559 {
10560 return false;
10561 }
10562 dim.push_back(dimlen);
10563 }
10564 }
10565 }
10566 else
10567 {
10568 while (current != ']')
10569 {
10570 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, inside_ndarray, current)))
10571 {
10572 return false;
10573 }
10574 dim.push_back(dimlen);
10575 get_ignore_noop();
10576 }
10577 }
10578 return true;
10579 }
10580
10588 bool get_ubjson_size_value(std::size_t& result, bool& inside_ndarray, char_int_type prefix = 0)
10589 {
10590 if (prefix == 0)
10591 {
10592 prefix = get_ignore_noop();
10593 }
10594
10595 switch (prefix)
10596 {
10597 case 'U':
10598 {
10599 std::uint8_t number{};
10600 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10601 {
10602 return false;
10603 }
10604 result = static_cast<std::size_t>(number);
10605 return true;
10606 }
10607
10608 case 'i':
10609 {
10610 std::int8_t number{};
10611 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10612 {
10613 return false;
10614 }
10615 if (number < 0)
10616 {
10617 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10618 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10619 }
10620 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10621 return true;
10622 }
10623
10624 case 'I':
10625 {
10626 std::int16_t number{};
10627 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10628 {
10629 return false;
10630 }
10631 if (number < 0)
10632 {
10633 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10634 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10635 }
10636 result = static_cast<std::size_t>(number);
10637 return true;
10638 }
10639
10640 case 'l':
10641 {
10642 std::int32_t number{};
10643 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10644 {
10645 return false;
10646 }
10647 if (number < 0)
10648 {
10649 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10650 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10651 }
10652 result = static_cast<std::size_t>(number);
10653 return true;
10654 }
10655
10656 case 'L':
10657 {
10658 std::int64_t number{};
10659 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10660 {
10661 return false;
10662 }
10663 if (number < 0)
10664 {
10665 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10666 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10667 }
10668 result = static_cast<std::size_t>(number);
10669 return true;
10670 }
10671
10672 case 'u':
10673 {
10674 if (input_format != input_format_t::bjdata)
10675 {
10676 break;
10677 }
10678 std::uint16_t number{};
10679 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10680 {
10681 return false;
10682 }
10683 result = static_cast<std::size_t>(number);
10684 return true;
10685 }
10686
10687 case 'm':
10688 {
10689 if (input_format != input_format_t::bjdata)
10690 {
10691 break;
10692 }
10693 std::uint32_t number{};
10694 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10695 {
10696 return false;
10697 }
10698 result = static_cast<std::size_t>(number);
10699 return true;
10700 }
10701
10702 case 'M':
10703 {
10704 if (input_format != input_format_t::bjdata)
10705 {
10706 break;
10707 }
10708 std::uint64_t number{};
10709 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10710 {
10711 return false;
10712 }
10713 result = detail::conditional_static_cast<std::size_t>(number);
10714 return true;
10715 }
10716
10717 case '[':
10718 {
10719 if (input_format != input_format_t::bjdata)
10720 {
10721 break;
10722 }
10723 if (inside_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
10724 {
10725 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimention vector can only contain integers", "size"), nullptr));
10726 }
10727 std::vector<size_t> dim;
10728 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
10729 {
10730 return false;
10731 }
10732 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
10733 {
10734 result = dim.at(dim.size() - 1);
10735 return true;
10736 }
10737 if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
10738 {
10739 for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
10740 {
10741 if (i == 0)
10742 {
10743 result = 0;
10744 return true;
10745 }
10746 }
10747
10748 string_t key = "_ArraySize_";
10749 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
10750 {
10751 return false;
10752 }
10753 result = 1;
10754 for (auto i : dim)
10755 {
10756 result *= i;
10757 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(static_cast<number_integer_t>(i))))
10758 {
10759 return false;
10760 }
10761 }
10762 inside_ndarray = true;
10763 return sax->end_array();
10764 }
10765 result = 0;
10766 return true;
10767 }
10768
10769 default:
10770 break;
10771 }
10772 auto last_token = get_token_string();
10773 std::string message;
10774
10775 if (input_format != input_format_t::bjdata)
10776 {
10777 message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
10778 }
10779 else
10780 {
10781 message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
10782 }
10783 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
10784 }
10785
10797 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
10798 {
10799 result.first = string_t::npos; // size
10800 result.second = 0; // type
10801 bool is_ndarray = false;
10802
10803 get_ignore_noop();
10804
10805 if (current == '$')
10806 {
10807 std::vector<char_int_type> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
10808
10809 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10810 if (JSON_HEDLEY_UNLIKELY(input_format == input_format_t::bjdata && std::find(bjdx.begin(), bjdx.end(), result.second) != bjdx.end()))
10811 {
10812 auto last_token = get_token_string();
10813 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10814 exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
10815 }
10816
10817 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
10818 {
10819 return false;
10820 }
10821
10822 get_ignore_noop();
10823 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10824 {
10825 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10826 {
10827 return false;
10828 }
10829 auto last_token = get_token_string();
10830 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10831 exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
10832 }
10833
10834 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
10835 if (input_format == input_format_t::bjdata && is_ndarray)
10836 {
10837 if (inside_ndarray)
10838 {
10839 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
10840 exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
10841 }
10842 result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
10843 }
10844 return is_error;
10845 }
10846
10847 if (current == '#')
10848 {
10849 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
10850 if (input_format == input_format_t::bjdata && is_ndarray)
10851 {
10852 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
10853 exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
10854 }
10855 return is_error;
10856 }
10857
10858 return true;
10859 }
10860
10865 bool get_ubjson_value(const char_int_type prefix)
10866 {
10867 switch (prefix)
10868 {
10869 case std::char_traits<char_type>::eof(): // EOF
10870 return unexpect_eof(input_format, "value");
10871
10872 case 'T': // true
10873 return sax->boolean(true);
10874 case 'F': // false
10875 return sax->boolean(false);
10876
10877 case 'Z': // null
10878 return sax->null();
10879
10880 case 'U':
10881 {
10882 std::uint8_t number{};
10883 return get_number(input_format, number) && sax->number_unsigned(number);
10884 }
10885
10886 case 'i':
10887 {
10888 std::int8_t number{};
10889 return get_number(input_format, number) && sax->number_integer(number);
10890 }
10891
10892 case 'I':
10893 {
10894 std::int16_t number{};
10895 return get_number(input_format, number) && sax->number_integer(number);
10896 }
10897
10898 case 'l':
10899 {
10900 std::int32_t number{};
10901 return get_number(input_format, number) && sax->number_integer(number);
10902 }
10903
10904 case 'L':
10905 {
10906 std::int64_t number{};
10907 return get_number(input_format, number) && sax->number_integer(number);
10908 }
10909
10910 case 'u':
10911 {
10912 if (input_format != input_format_t::bjdata)
10913 {
10914 break;
10915 }
10916 std::uint16_t number{};
10917 return get_number(input_format, number) && sax->number_unsigned(number);
10918 }
10919
10920 case 'm':
10921 {
10922 if (input_format != input_format_t::bjdata)
10923 {
10924 break;
10925 }
10926 std::uint32_t number{};
10927 return get_number(input_format, number) && sax->number_unsigned(number);
10928 }
10929
10930 case 'M':
10931 {
10932 if (input_format != input_format_t::bjdata)
10933 {
10934 break;
10935 }
10936 std::uint64_t number{};
10937 return get_number(input_format, number) && sax->number_unsigned(number);
10938 }
10939
10940 case 'h':
10941 {
10942 if (input_format != input_format_t::bjdata)
10943 {
10944 break;
10945 }
10946 const auto byte1_raw = get();
10947 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
10948 {
10949 return false;
10950 }
10951 const auto byte2_raw = get();
10952 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
10953 {
10954 return false;
10955 }
10956
10957 const auto byte1 = static_cast<unsigned char>(byte1_raw);
10958 const auto byte2 = static_cast<unsigned char>(byte2_raw);
10959
10960 // code from RFC 7049, Appendix D, Figure 3:
10961 // As half-precision floating-point numbers were only added
10962 // to IEEE 754 in 2008, today's programming platforms often
10963 // still only have limited support for them. It is very
10964 // easy to include at least decoding support for them even
10965 // without such support. An example of a small decoder for
10966 // half-precision floating-point numbers in the C language
10967 // is shown in Fig. 3.
10968 const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
10969 const double val = [&half]
10970 {
10971 const int exp = (half >> 10u) & 0x1Fu;
10972 const unsigned int mant = half & 0x3FFu;
10973 JSON_ASSERT(0 <= exp && exp <= 32);
10974 JSON_ASSERT(mant <= 1024);
10975 switch (exp)
10976 {
10977 case 0:
10978 return std::ldexp(mant, -24);
10979 case 31:
10980 return (mant == 0)
10981 ? std::numeric_limits<double>::infinity()
10982 : std::numeric_limits<double>::quiet_NaN();
10983 default:
10984 return std::ldexp(mant + 1024, exp - 25);
10985 }
10986 }();
10987 return sax->number_float((half & 0x8000u) != 0
10988 ? static_cast<number_float_t>(-val)
10989 : static_cast<number_float_t>(val), "");
10990 }
10991
10992 case 'd':
10993 {
10994 float number{};
10995 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
10996 }
10997
10998 case 'D':
10999 {
11000 double number{};
11001 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11002 }
11003
11004 case 'H':
11005 {
11006 return get_ubjson_high_precision_number();
11007 }
11008
11009 case 'C': // char
11010 {
11011 get();
11012 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11013 {
11014 return false;
11015 }
11016 if (JSON_HEDLEY_UNLIKELY(current > 127))
11017 {
11018 auto last_token = get_token_string();
11019 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11020 exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11021 }
11022 string_t s(1, static_cast<typename string_t::value_type>(current));
11023 return sax->string(s);
11024 }
11025
11026 case 'S': // string
11027 {
11028 string_t s;
11029 return get_ubjson_string(s) && sax->string(s);
11030 }
11031
11032 case '[': // array
11033 return get_ubjson_array();
11034
11035 case '{': // object
11036 return get_ubjson_object();
11037
11038 default: // anything else
11039 break;
11040 }
11041 auto last_token = get_token_string();
11042 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
11043 }
11044
11048 bool get_ubjson_array()
11049 {
11050 std::pair<std::size_t, char_int_type> size_and_type;
11051 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11052 {
11053 return false;
11054 }
11055
11056 // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
11057 // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11058
11059 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
11060 {
11061 std::map<char_int_type, string_t> bjdtype = { {'U', "uint8"}, {'i', "int8"}, {'u', "uint16"}, {'I', "int16"},
11062 {'m', "uint32"}, {'l', "int32"}, {'M', "uint64"}, {'L', "int64"}, {'d', "single"}, {'D', "double"}, {'C', "char"}
11063 };
11064
11065 size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
11066
11067 string_t key = "_ArrayType_";
11068 if (JSON_HEDLEY_UNLIKELY(bjdtype.count(size_and_type.second) == 0))
11069 {
11070 auto last_token = get_token_string();
11071 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11072 exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11073 }
11074
11075 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(bjdtype[size_and_type.second])))
11076 {
11077 return false;
11078 }
11079
11080 if (size_and_type.second == 'C')
11081 {
11082 size_and_type.second = 'U';
11083 }
11084
11085 key = "_ArrayData_";
11086 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first)))
11087 {
11088 return false;
11089 }
11090
11091 for (std::size_t i = 0; i < size_and_type.first; ++i)
11092 {
11093 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11094 {
11095 return false;
11096 }
11097 }
11098
11099 return (sax->end_array() && sax->end_object());
11100 }
11101
11102 if (size_and_type.first != string_t::npos)
11103 {
11104 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11105 {
11106 return false;
11107 }
11108
11109 if (size_and_type.second != 0)
11110 {
11111 if (size_and_type.second != 'N')
11112 {
11113 for (std::size_t i = 0; i < size_and_type.first; ++i)
11114 {
11115 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11116 {
11117 return false;
11118 }
11119 }
11120 }
11121 }
11122 else
11123 {
11124 for (std::size_t i = 0; i < size_and_type.first; ++i)
11125 {
11126 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11127 {
11128 return false;
11129 }
11130 }
11131 }
11132 }
11133 else
11134 {
11135 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11136 {
11137 return false;
11138 }
11139
11140 while (current != ']')
11141 {
11142 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11143 {
11144 return false;
11145 }
11146 get_ignore_noop();
11147 }
11148 }
11149
11150 return sax->end_array();
11151 }
11152
11156 bool get_ubjson_object()
11157 {
11158 std::pair<std::size_t, char_int_type> size_and_type;
11159 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11160 {
11161 return false;
11162 }
11163
11164 // do not accept ND-array size in objects in BJData
11165 if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
11166 {
11167 auto last_token = get_token_string();
11168 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11169 exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11170 }
11171
11172 string_t key;
11173 if (size_and_type.first != string_t::npos)
11174 {
11175 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11176 {
11177 return false;
11178 }
11179
11180 if (size_and_type.second != 0)
11181 {
11182 for (std::size_t i = 0; i < size_and_type.first; ++i)
11183 {
11184 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11185 {
11186 return false;
11187 }
11188 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11189 {
11190 return false;
11191 }
11192 key.clear();
11193 }
11194 }
11195 else
11196 {
11197 for (std::size_t i = 0; i < size_and_type.first; ++i)
11198 {
11199 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11200 {
11201 return false;
11202 }
11203 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11204 {
11205 return false;
11206 }
11207 key.clear();
11208 }
11209 }
11210 }
11211 else
11212 {
11213 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11214 {
11215 return false;
11216 }
11217
11218 while (current != '}')
11219 {
11220 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11221 {
11222 return false;
11223 }
11224 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11225 {
11226 return false;
11227 }
11228 get_ignore_noop();
11229 key.clear();
11230 }
11231 }
11232
11233 return sax->end_object();
11234 }
11235
11236 // Note, no reader for UBJSON binary types is implemented because they do
11237 // not exist
11238
11239 bool get_ubjson_high_precision_number()
11240 {
11241 // get size of following number string
11242 std::size_t size{};
11243 bool inside_ndarray = false;
11244 auto res = get_ubjson_size_value(size, inside_ndarray);
11245 if (JSON_HEDLEY_UNLIKELY(!res))
11246 {
11247 return res;
11248 }
11249
11250 // get number string
11251 std::vector<char> number_vector;
11252 for (std::size_t i = 0; i < size; ++i)
11253 {
11254 get();
11255 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11256 {
11257 return false;
11258 }
11259 number_vector.push_back(static_cast<char>(current));
11260 }
11261
11262 // parse number string
11263 using ia_type = decltype(detail::input_adapter(number_vector));
11264 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11265 const auto result_number = number_lexer.scan();
11266 const auto number_string = number_lexer.get_token_string();
11267 const auto result_remainder = number_lexer.scan();
11268
11269 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11270
11271 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11272 {
11273 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11274 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11275 }
11276
11277 switch (result_number)
11278 {
11279 case token_type::value_integer:
11280 return sax->number_integer(number_lexer.get_number_integer());
11281 case token_type::value_unsigned:
11282 return sax->number_unsigned(number_lexer.get_number_unsigned());
11283 case token_type::value_float:
11284 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11285 case token_type::uninitialized:
11286 case token_type::literal_true:
11287 case token_type::literal_false:
11288 case token_type::literal_null:
11289 case token_type::value_string:
11290 case token_type::begin_array:
11291 case token_type::begin_object:
11292 case token_type::end_array:
11293 case token_type::end_object:
11294 case token_type::name_separator:
11295 case token_type::value_separator:
11296 case token_type::parse_error:
11297 case token_type::end_of_input:
11298 case token_type::literal_or_value:
11299 default:
11300 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11301 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11302 }
11303 }
11304
11306 // Utility functions //
11308
11318 char_int_type get()
11319 {
11320 ++chars_read;
11321 return current = ia.get_character();
11322 }
11323
11327 char_int_type get_ignore_noop()
11328 {
11329 do
11330 {
11331 get();
11332 } while (current == 'N');
11333
11334 return current;
11335 }
11336
11337 /*
11338 @brief read a number from the input
11339
11340 @tparam NumberType the type of the number
11341 @param[in] format the current format (for diagnostics)
11342 @param[out] result number of type @a NumberType
11343
11344 @return whether conversion completed
11345
11346 @note This function needs to respect the system's endianness, because
11347 bytes in CBOR, MessagePack, and UBJSON are stored in network order
11348 (big endian) and therefore need reordering on little endian systems.
11349 On the other hand, BSON and BJData use little endian and should reorder
11350 on big endian systems.
11351 */
11352 template<typename NumberType, bool InputIsLittleEndian = false>
11353 bool get_number(const input_format_t format, NumberType& result)
11354 {
11355 // step 1: read input into array with system's byte order
11356 std::array<std::uint8_t, sizeof(NumberType)> vec{};
11357 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11358 {
11359 get();
11360 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11361 {
11362 return false;
11363 }
11364
11365 // reverse byte order prior to conversion if necessary
11366 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11367 {
11368 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11369 }
11370 else
11371 {
11372 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11373 }
11374 }
11375
11376 // step 2: convert array into number of type T and return
11377 std::memcpy(&result, vec.data(), sizeof(NumberType));
11378 return true;
11379 }
11380
11395 template<typename NumberType>
11396 bool get_string(const input_format_t format,
11397 const NumberType len,
11398 string_t& result)
11399 {
11400 bool success = true;
11401 for (NumberType i = 0; i < len; i++)
11402 {
11403 get();
11404 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11405 {
11406 success = false;
11407 break;
11408 }
11409 result.push_back(static_cast<typename string_t::value_type>(current));
11410 }
11411 return success;
11412 }
11413
11428 template<typename NumberType>
11429 bool get_binary(const input_format_t format,
11430 const NumberType len,
11431 binary_t& result)
11432 {
11433 bool success = true;
11434 for (NumberType i = 0; i < len; i++)
11435 {
11436 get();
11437 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11438 {
11439 success = false;
11440 break;
11441 }
11442 result.push_back(static_cast<std::uint8_t>(current));
11443 }
11444 return success;
11445 }
11446
11453 bool unexpect_eof(const input_format_t format, const char* context) const
11454 {
11455 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11456 {
11457 return sax->parse_error(chars_read, "<end of file>",
11458 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11459 }
11460 return true;
11461 }
11462
11466 std::string get_token_string() const
11467 {
11468 std::array<char, 3> cr{ {} };
11469 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11470 return std::string{ cr.data() };
11471 }
11472
11479 std::string exception_message(const input_format_t format,
11480 const std::string& detail,
11481 const std::string& context) const
11482 {
11483 std::string error_msg = "syntax error while parsing ";
11484
11485 switch (format)
11486 {
11488 error_msg += "CBOR";
11489 break;
11490
11492 error_msg += "MessagePack";
11493 break;
11494
11496 error_msg += "UBJSON";
11497 break;
11498
11500 error_msg += "BSON";
11501 break;
11502
11504 error_msg += "BJData";
11505 break;
11506
11507 case input_format_t::json: // LCOV_EXCL_LINE
11508 default: // LCOV_EXCL_LINE
11509 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
11510 }
11511
11512 return concat(error_msg, ' ', context, ": ", detail);
11513 }
11514
11515 private:
11517 InputAdapterType ia;
11518
11520 char_int_type current = std::char_traits<char_type>::eof();
11521
11523 std::size_t chars_read = 0;
11524
11526 const bool is_little_endian = little_endianness();
11527
11529 const input_format_t input_format = input_format_t::json;
11530
11532 json_sax_t* sax = nullptr;
11533 };
11534 } // namespace detail
11535} // namespace nlohmann
11536
11537// #include <nlohmann/detail/input/input_adapters.hpp>
11538
11539// #include <nlohmann/detail/input/lexer.hpp>
11540
11541// #include <nlohmann/detail/input/parser.hpp>
11542
11543
11544#include <cmath> // isfinite
11545#include <cstdint> // uint8_t
11546#include <functional> // function
11547#include <string> // string
11548#include <utility> // move
11549#include <vector> // vector
11550
11551// #include <nlohmann/detail/exceptions.hpp>
11552
11553// #include <nlohmann/detail/input/input_adapters.hpp>
11554
11555// #include <nlohmann/detail/input/json_sax.hpp>
11556
11557// #include <nlohmann/detail/input/lexer.hpp>
11558
11559// #include <nlohmann/detail/macro_scope.hpp>
11560
11561// #include <nlohmann/detail/meta/is_sax.hpp>
11562
11563// #include <nlohmann/detail/string_concat.hpp>
11564
11565// #include <nlohmann/detail/value_t.hpp>
11566
11567
11568namespace nlohmann
11569{
11570 namespace detail
11571 {
11573 // parser //
11575
11576 enum class parse_event_t : std::uint8_t
11577 {
11581 object_end,
11585 array_end,
11587 key,
11589 value
11590 };
11591
11592 template<typename BasicJsonType>
11594 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
11595
11601 template<typename BasicJsonType, typename InputAdapterType>
11603 {
11604 using number_integer_t = typename BasicJsonType::number_integer_t;
11605 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
11606 using number_float_t = typename BasicJsonType::number_float_t;
11607 using string_t = typename BasicJsonType::string_t;
11609 using token_type = typename lexer_t::token_type;
11610
11611 public:
11613 explicit parser(InputAdapterType&& adapter,
11614 const parser_callback_t<BasicJsonType> cb = nullptr,
11615 const bool allow_exceptions_ = true,
11616 const bool skip_comments = false)
11617 : callback(cb)
11618 , m_lexer(std::move(adapter), skip_comments)
11619 , allow_exceptions(allow_exceptions_)
11620 {
11621 // read first token
11622 get_token();
11623 }
11624
11635 void parse(const bool strict, BasicJsonType& result)
11636 {
11637 if (callback)
11638 {
11639 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11640 sax_parse_internal(&sdp);
11641
11642 // in strict mode, input must be completely read
11643 if (strict && (get_token() != token_type::end_of_input))
11644 {
11645 sdp.parse_error(m_lexer.get_position(),
11646 m_lexer.get_token_string(),
11647 parse_error::create(101, m_lexer.get_position(),
11648 exception_message(token_type::end_of_input, "value"), nullptr));
11649 }
11650
11651 // in case of an error, return discarded value
11652 if (sdp.is_errored())
11653 {
11654 result = value_t::discarded;
11655 return;
11656 }
11657
11658 // set top-level value to null if it was discarded by the callback
11659 // function
11660 if (result.is_discarded())
11661 {
11662 result = nullptr;
11663 }
11664 }
11665 else
11666 {
11667 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11668 sax_parse_internal(&sdp);
11669
11670 // in strict mode, input must be completely read
11671 if (strict && (get_token() != token_type::end_of_input))
11672 {
11673 sdp.parse_error(m_lexer.get_position(),
11674 m_lexer.get_token_string(),
11675 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11676 }
11677
11678 // in case of an error, return discarded value
11679 if (sdp.is_errored())
11680 {
11681 result = value_t::discarded;
11682 return;
11683 }
11684 }
11685
11686 result.assert_invariant();
11687 }
11688
11695 bool accept(const bool strict = true)
11696 {
11698 return sax_parse(&sax_acceptor, strict);
11699 }
11700
11701 template<typename SAX>
11703 bool sax_parse(SAX* sax, const bool strict = true)
11704 {
11706 const bool result = sax_parse_internal(sax);
11707
11708 // strict mode: next byte must be EOF
11709 if (result && strict && (get_token() != token_type::end_of_input))
11710 {
11711 return sax->parse_error(m_lexer.get_position(),
11712 m_lexer.get_token_string(),
11713 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11714 }
11715
11716 return result;
11717 }
11718
11719 private:
11720 template<typename SAX>
11722 bool sax_parse_internal(SAX* sax)
11723 {
11724 // stack to remember the hierarchy of structured values we are parsing
11725 // true = array; false = object
11726 std::vector<bool> states;
11727 // value to avoid a goto (see comment where set to true)
11728 bool skip_to_state_evaluation = false;
11729
11730 while (true)
11731 {
11732 if (!skip_to_state_evaluation)
11733 {
11734 // invariant: get_token() was called before each iteration
11735 switch (last_token)
11736 {
11737 case token_type::begin_object:
11738 {
11739 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11740 {
11741 return false;
11742 }
11743
11744 // closing } -> we are done
11745 if (get_token() == token_type::end_object)
11746 {
11747 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11748 {
11749 return false;
11750 }
11751 break;
11752 }
11753
11754 // parse key
11755 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11756 {
11757 return sax->parse_error(m_lexer.get_position(),
11758 m_lexer.get_token_string(),
11759 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
11760 }
11761 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11762 {
11763 return false;
11764 }
11765
11766 // parse separator (:)
11767 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11768 {
11769 return sax->parse_error(m_lexer.get_position(),
11770 m_lexer.get_token_string(),
11771 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
11772 }
11773
11774 // remember we are now inside an object
11775 states.push_back(false);
11776
11777 // parse values
11778 get_token();
11779 continue;
11780 }
11781
11782 case token_type::begin_array:
11783 {
11784 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11785 {
11786 return false;
11787 }
11788
11789 // closing ] -> we are done
11790 if (get_token() == token_type::end_array)
11791 {
11792 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11793 {
11794 return false;
11795 }
11796 break;
11797 }
11798
11799 // remember we are now inside an array
11800 states.push_back(true);
11801
11802 // parse values (no need to call get_token)
11803 continue;
11804 }
11805
11806 case token_type::value_float:
11807 {
11808 const auto res = m_lexer.get_number_float();
11809
11810 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11811 {
11812 return sax->parse_error(m_lexer.get_position(),
11813 m_lexer.get_token_string(),
11814 out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
11815 }
11816
11817 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11818 {
11819 return false;
11820 }
11821
11822 break;
11823 }
11824
11825 case token_type::literal_false:
11826 {
11827 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11828 {
11829 return false;
11830 }
11831 break;
11832 }
11833
11834 case token_type::literal_null:
11835 {
11836 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11837 {
11838 return false;
11839 }
11840 break;
11841 }
11842
11843 case token_type::literal_true:
11844 {
11845 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11846 {
11847 return false;
11848 }
11849 break;
11850 }
11851
11852 case token_type::value_integer:
11853 {
11854 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11855 {
11856 return false;
11857 }
11858 break;
11859 }
11860
11861 case token_type::value_string:
11862 {
11863 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11864 {
11865 return false;
11866 }
11867 break;
11868 }
11869
11870 case token_type::value_unsigned:
11871 {
11872 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11873 {
11874 return false;
11875 }
11876 break;
11877 }
11878
11879 case token_type::parse_error:
11880 {
11881 // using "uninitialized" to avoid "expected" message
11882 return sax->parse_error(m_lexer.get_position(),
11883 m_lexer.get_token_string(),
11884 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
11885 }
11886
11887 case token_type::uninitialized:
11888 case token_type::end_array:
11889 case token_type::end_object:
11890 case token_type::name_separator:
11891 case token_type::value_separator:
11892 case token_type::end_of_input:
11893 case token_type::literal_or_value:
11894 default: // the last token was unexpected
11895 {
11896 return sax->parse_error(m_lexer.get_position(),
11897 m_lexer.get_token_string(),
11898 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
11899 }
11900 }
11901 }
11902 else
11903 {
11904 skip_to_state_evaluation = false;
11905 }
11906
11907 // we reached this line after we successfully parsed a value
11908 if (states.empty())
11909 {
11910 // empty stack: we reached the end of the hierarchy: done
11911 return true;
11912 }
11913
11914 if (states.back()) // array
11915 {
11916 // comma -> next value
11917 if (get_token() == token_type::value_separator)
11918 {
11919 // parse a new value
11920 get_token();
11921 continue;
11922 }
11923
11924 // closing ]
11925 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11926 {
11927 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11928 {
11929 return false;
11930 }
11931
11932 // We are done with this array. Before we can parse a
11933 // new value, we need to evaluate the new state first.
11934 // By setting skip_to_state_evaluation to false, we
11935 // are effectively jumping to the beginning of this if.
11936 JSON_ASSERT(!states.empty());
11937 states.pop_back();
11938 skip_to_state_evaluation = true;
11939 continue;
11940 }
11941
11942 return sax->parse_error(m_lexer.get_position(),
11943 m_lexer.get_token_string(),
11944 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
11945 }
11946
11947 // states.back() is false -> object
11948
11949 // comma -> next value
11950 if (get_token() == token_type::value_separator)
11951 {
11952 // parse key
11953 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11954 {
11955 return sax->parse_error(m_lexer.get_position(),
11956 m_lexer.get_token_string(),
11957 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
11958 }
11959
11960 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11961 {
11962 return false;
11963 }
11964
11965 // parse separator (:)
11966 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11967 {
11968 return sax->parse_error(m_lexer.get_position(),
11969 m_lexer.get_token_string(),
11970 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
11971 }
11972
11973 // parse values
11974 get_token();
11975 continue;
11976 }
11977
11978 // closing }
11979 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11980 {
11981 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11982 {
11983 return false;
11984 }
11985
11986 // We are done with this object. Before we can parse a
11987 // new value, we need to evaluate the new state first.
11988 // By setting skip_to_state_evaluation to false, we
11989 // are effectively jumping to the beginning of this if.
11990 JSON_ASSERT(!states.empty());
11991 states.pop_back();
11992 skip_to_state_evaluation = true;
11993 continue;
11994 }
11995
11996 return sax->parse_error(m_lexer.get_position(),
11997 m_lexer.get_token_string(),
11998 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
11999 }
12000 }
12001
12003 token_type get_token()
12004 {
12005 return last_token = m_lexer.scan();
12006 }
12007
12008 std::string exception_message(const token_type expected, const std::string& context)
12009 {
12010 std::string error_msg = "syntax error ";
12011
12012 if (!context.empty())
12013 {
12014 error_msg += concat("while parsing ", context, ' ');
12015 }
12016
12017 error_msg += "- ";
12018
12019 if (last_token == token_type::parse_error)
12020 {
12021 error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12022 m_lexer.get_token_string(), '\'');
12023 }
12024 else
12025 {
12026 error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12027 }
12028
12029 if (expected != token_type::uninitialized)
12030 {
12031 error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12032 }
12033
12034 return error_msg;
12035 }
12036
12037 private:
12039 const parser_callback_t<BasicJsonType> callback = nullptr;
12041 token_type last_token = token_type::uninitialized;
12043 lexer_t m_lexer;
12045 const bool allow_exceptions = true;
12046 };
12047
12048 } // namespace detail
12049} // namespace nlohmann
12050
12051// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12052
12053
12054// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12055
12056
12057#include <cstddef> // ptrdiff_t
12058#include <limits> // numeric_limits
12059
12060// #include <nlohmann/detail/macro_scope.hpp>
12061
12062
12063namespace nlohmann
12064{
12065 namespace detail
12066 {
12067 /*
12068 @brief an iterator for primitive JSON types
12069
12070 This class models an iterator for primitive JSON types (boolean, number,
12071 string). It's only purpose is to allow the iterator/const_iterator classes
12072 to "iterate" over primitive values. Internally, the iterator is modeled by
12073 a `difference_type` variable. Value begin_value (`0`) models the begin,
12074 end_value (`1`) models past the end.
12075 */
12077 {
12078 private:
12079 using difference_type = std::ptrdiff_t;
12080 static constexpr difference_type begin_value = 0;
12081 static constexpr difference_type end_value = begin_value + 1;
12082
12085 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12086
12087 public:
12088 constexpr difference_type get_value() const noexcept
12089 {
12090 return m_it;
12091 }
12092
12094 void set_begin() noexcept
12095 {
12096 m_it = begin_value;
12097 }
12098
12100 void set_end() noexcept
12101 {
12102 m_it = end_value;
12103 }
12104
12106 constexpr bool is_begin() const noexcept
12107 {
12108 return m_it == begin_value;
12109 }
12110
12112 constexpr bool is_end() const noexcept
12113 {
12114 return m_it == end_value;
12115 }
12116
12117 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12118 {
12119 return lhs.m_it == rhs.m_it;
12120 }
12121
12122 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12123 {
12124 return lhs.m_it < rhs.m_it;
12125 }
12126
12127 primitive_iterator_t operator+(difference_type n) noexcept
12128 {
12129 auto result = *this;
12130 result += n;
12131 return result;
12132 }
12133
12134 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12135 {
12136 return lhs.m_it - rhs.m_it;
12137 }
12138
12140 {
12141 ++m_it;
12142 return *this;
12143 }
12144
12145 primitive_iterator_t operator++(int)&noexcept // NOLINT(cert-dcl21-cpp)
12146 {
12147 auto result = *this;
12148 ++m_it;
12149 return result;
12150 }
12151
12153 {
12154 --m_it;
12155 return *this;
12156 }
12157
12158 primitive_iterator_t operator--(int)&noexcept // NOLINT(cert-dcl21-cpp)
12159 {
12160 auto result = *this;
12161 --m_it;
12162 return result;
12163 }
12164
12165 primitive_iterator_t& operator+=(difference_type n) noexcept
12166 {
12167 m_it += n;
12168 return *this;
12169 }
12170
12171 primitive_iterator_t& operator-=(difference_type n) noexcept
12172 {
12173 m_it -= n;
12174 return *this;
12175 }
12176 };
12177 } // namespace detail
12178} // namespace nlohmann
12179
12180
12181namespace nlohmann
12182{
12183 namespace detail
12184 {
12191 template<typename BasicJsonType> struct internal_iterator
12192 {
12194 typename BasicJsonType::object_t::iterator object_iterator{};
12196 typename BasicJsonType::array_t::iterator array_iterator{};
12199 };
12200 } // namespace detail
12201} // namespace nlohmann
12202
12203// #include <nlohmann/detail/iterators/iter_impl.hpp>
12204
12205
12206#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12207#include <type_traits> // conditional, is_const, remove_const
12208
12209// #include <nlohmann/detail/exceptions.hpp>
12210
12211// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12212
12213// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12214
12215// #include <nlohmann/detail/macro_scope.hpp>
12216
12217// #include <nlohmann/detail/meta/cpp_future.hpp>
12218
12219// #include <nlohmann/detail/meta/type_traits.hpp>
12220
12221// #include <nlohmann/detail/value_t.hpp>
12222
12223
12224namespace nlohmann
12225{
12226 namespace detail
12227 {
12228 // forward declare, to be able to friend it later on
12229 template<typename IteratorType> class iteration_proxy;
12230 template<typename IteratorType> class iteration_proxy_value;
12231
12248 template<typename BasicJsonType>
12249 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12250 {
12252 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12254 friend other_iter_impl;
12255 friend BasicJsonType;
12258
12259 using object_t = typename BasicJsonType::object_t;
12260 using array_t = typename BasicJsonType::array_t;
12261 // make sure BasicJsonType is basic_json or const basic_json
12263 "iter_impl only accepts (const) basic_json");
12264 // superficial check for the LegacyBidirectionalIterator named requirement
12265 static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12266 && std::is_base_of<std::bidirectional_iterator_tag, typename array_t::iterator::iterator_category>::value,
12267 "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12268
12269 public:
12275 using iterator_category = std::bidirectional_iterator_tag;
12276
12278 using value_type = typename BasicJsonType::value_type;
12280 using difference_type = typename BasicJsonType::difference_type;
12282 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12283 typename BasicJsonType::const_pointer,
12284 typename BasicJsonType::pointer>::type;
12287 typename std::conditional<std::is_const<BasicJsonType>::value,
12288 typename BasicJsonType::const_reference,
12289 typename BasicJsonType::reference>::type;
12290
12291 iter_impl() = default;
12292 ~iter_impl() = default;
12293 iter_impl(iter_impl&&) noexcept = default;
12294 iter_impl& operator=(iter_impl&&) noexcept = default;
12295
12302 explicit iter_impl(pointer object) noexcept : m_object(object)
12303 {
12304 JSON_ASSERT(m_object != nullptr);
12305
12306 switch (m_object->m_type)
12307 {
12308 case value_t::object:
12309 {
12310 m_it.object_iterator = typename object_t::iterator();
12311 break;
12312 }
12313
12314 case value_t::array:
12315 {
12316 m_it.array_iterator = typename array_t::iterator();
12317 break;
12318 }
12319
12320 case value_t::null:
12321 case value_t::string:
12322 case value_t::boolean:
12326 case value_t::binary:
12327 case value_t::discarded:
12328 default:
12329 {
12331 break;
12332 }
12333 }
12334 }
12335
12353 : m_object(other.m_object), m_it(other.m_it)
12354 {}
12355
12363 {
12364 if (&other != this)
12365 {
12366 m_object = other.m_object;
12367 m_it = other.m_it;
12368 }
12369 return *this;
12370 }
12371
12377 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
12378 : m_object(other.m_object), m_it(other.m_it)
12379 {}
12380
12387 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12388 {
12389 m_object = other.m_object;
12390 m_it = other.m_it;
12391 return *this;
12392 }
12393
12399 void set_begin() noexcept
12400 {
12401 JSON_ASSERT(m_object != nullptr);
12402
12403 switch (m_object->m_type)
12404 {
12405 case value_t::object:
12406 {
12407 m_it.object_iterator = m_object->m_value.object->begin();
12408 break;
12409 }
12410
12411 case value_t::array:
12412 {
12413 m_it.array_iterator = m_object->m_value.array->begin();
12414 break;
12415 }
12416
12417 case value_t::null:
12418 {
12419 // set to end so begin()==end() is true: null is empty
12421 break;
12422 }
12423
12424 case value_t::string:
12425 case value_t::boolean:
12429 case value_t::binary:
12430 case value_t::discarded:
12431 default:
12432 {
12434 break;
12435 }
12436 }
12437 }
12438
12443 void set_end() noexcept
12444 {
12445 JSON_ASSERT(m_object != nullptr);
12446
12447 switch (m_object->m_type)
12448 {
12449 case value_t::object:
12450 {
12451 m_it.object_iterator = m_object->m_value.object->end();
12452 break;
12453 }
12454
12455 case value_t::array:
12456 {
12457 m_it.array_iterator = m_object->m_value.array->end();
12458 break;
12459 }
12460
12461 case value_t::null:
12462 case value_t::string:
12463 case value_t::boolean:
12467 case value_t::binary:
12468 case value_t::discarded:
12469 default:
12470 {
12472 break;
12473 }
12474 }
12475 }
12476
12477 public:
12483 {
12484 JSON_ASSERT(m_object != nullptr);
12485
12486 switch (m_object->m_type)
12487 {
12488 case value_t::object:
12489 {
12490 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12491 return m_it.object_iterator->second;
12492 }
12493
12494 case value_t::array:
12495 {
12496 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12497 return *m_it.array_iterator;
12498 }
12499
12500 case value_t::null:
12501 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12502
12503 case value_t::string:
12504 case value_t::boolean:
12508 case value_t::binary:
12509 case value_t::discarded:
12510 default:
12511 {
12513 {
12514 return *m_object;
12515 }
12516
12517 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12518 }
12519 }
12520 }
12521
12527 {
12528 JSON_ASSERT(m_object != nullptr);
12529
12530 switch (m_object->m_type)
12531 {
12532 case value_t::object:
12533 {
12534 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12535 return &(m_it.object_iterator->second);
12536 }
12537
12538 case value_t::array:
12539 {
12540 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12541 return &*m_it.array_iterator;
12542 }
12543
12544 case value_t::null:
12545 case value_t::string:
12546 case value_t::boolean:
12550 case value_t::binary:
12551 case value_t::discarded:
12552 default:
12553 {
12555 {
12556 return m_object;
12557 }
12558
12559 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12560 }
12561 }
12562 }
12563
12568 iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
12569 {
12570 auto result = *this;
12571 ++(*this);
12572 return result;
12573 }
12574
12580 {
12581 JSON_ASSERT(m_object != nullptr);
12582
12583 switch (m_object->m_type)
12584 {
12585 case value_t::object:
12586 {
12587 std::advance(m_it.object_iterator, 1);
12588 break;
12589 }
12590
12591 case value_t::array:
12592 {
12593 std::advance(m_it.array_iterator, 1);
12594 break;
12595 }
12596
12597 case value_t::null:
12598 case value_t::string:
12599 case value_t::boolean:
12603 case value_t::binary:
12604 case value_t::discarded:
12605 default:
12606 {
12608 break;
12609 }
12610 }
12611
12612 return *this;
12613 }
12614
12619 iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
12620 {
12621 auto result = *this;
12622 --(*this);
12623 return result;
12624 }
12625
12631 {
12632 JSON_ASSERT(m_object != nullptr);
12633
12634 switch (m_object->m_type)
12635 {
12636 case value_t::object:
12637 {
12638 std::advance(m_it.object_iterator, -1);
12639 break;
12640 }
12641
12642 case value_t::array:
12643 {
12644 std::advance(m_it.array_iterator, -1);
12645 break;
12646 }
12647
12648 case value_t::null:
12649 case value_t::string:
12650 case value_t::boolean:
12654 case value_t::binary:
12655 case value_t::discarded:
12656 default:
12657 {
12659 break;
12660 }
12661 }
12662
12663 return *this;
12664 }
12665
12670 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12671 bool operator==(const IterImpl& other) const
12672 {
12673 // if objects are not the same, the comparison is undefined
12674 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12675 {
12676 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12677 }
12678
12679 JSON_ASSERT(m_object != nullptr);
12680
12681 switch (m_object->m_type)
12682 {
12683 case value_t::object:
12684 return (m_it.object_iterator == other.m_it.object_iterator);
12685
12686 case value_t::array:
12687 return (m_it.array_iterator == other.m_it.array_iterator);
12688
12689 case value_t::null:
12690 case value_t::string:
12691 case value_t::boolean:
12695 case value_t::binary:
12696 case value_t::discarded:
12697 default:
12698 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12699 }
12700 }
12701
12706 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12707 bool operator!=(const IterImpl& other) const
12708 {
12709 return !operator==(other);
12710 }
12711
12716 bool operator<(const iter_impl& other) const
12717 {
12718 // if objects are not the same, the comparison is undefined
12719 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12720 {
12721 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12722 }
12723
12724 JSON_ASSERT(m_object != nullptr);
12725
12726 switch (m_object->m_type)
12727 {
12728 case value_t::object:
12729 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
12730
12731 case value_t::array:
12732 return (m_it.array_iterator < other.m_it.array_iterator);
12733
12734 case value_t::null:
12735 case value_t::string:
12736 case value_t::boolean:
12740 case value_t::binary:
12741 case value_t::discarded:
12742 default:
12744 }
12745 }
12746
12751 bool operator<=(const iter_impl& other) const
12752 {
12753 return !other.operator < (*this);
12754 }
12755
12760 bool operator>(const iter_impl& other) const
12761 {
12762 return !operator<=(other);
12763 }
12764
12769 bool operator>=(const iter_impl& other) const
12770 {
12771 return !operator<(other);
12772 }
12773
12779 {
12780 JSON_ASSERT(m_object != nullptr);
12781
12782 switch (m_object->m_type)
12783 {
12784 case value_t::object:
12785 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12786
12787 case value_t::array:
12788 {
12789 std::advance(m_it.array_iterator, i);
12790 break;
12791 }
12792
12793 case value_t::null:
12794 case value_t::string:
12795 case value_t::boolean:
12799 case value_t::binary:
12800 case value_t::discarded:
12801 default:
12802 {
12804 break;
12805 }
12806 }
12807
12808 return *this;
12809 }
12810
12816 {
12817 return operator+=(-i);
12818 }
12819
12825 {
12826 auto result = *this;
12827 result += i;
12828 return result;
12829 }
12830
12836 {
12837 auto result = it;
12838 result += i;
12839 return result;
12840 }
12841
12847 {
12848 auto result = *this;
12849 result -= i;
12850 return result;
12851 }
12852
12858 {
12859 JSON_ASSERT(m_object != nullptr);
12860
12861 switch (m_object->m_type)
12862 {
12863 case value_t::object:
12864 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12865
12866 case value_t::array:
12867 return m_it.array_iterator - other.m_it.array_iterator;
12868
12869 case value_t::null:
12870 case value_t::string:
12871 case value_t::boolean:
12875 case value_t::binary:
12876 case value_t::discarded:
12877 default:
12879 }
12880 }
12881
12887 {
12888 JSON_ASSERT(m_object != nullptr);
12889
12890 switch (m_object->m_type)
12891 {
12892 case value_t::object:
12893 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
12894
12895 case value_t::array:
12896 return *std::next(m_it.array_iterator, n);
12897
12898 case value_t::null:
12899 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12900
12901 case value_t::string:
12902 case value_t::boolean:
12906 case value_t::binary:
12907 case value_t::discarded:
12908 default:
12909 {
12911 {
12912 return *m_object;
12913 }
12914
12915 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12916 }
12917 }
12918 }
12919
12924 const typename object_t::key_type& key() const
12925 {
12926 JSON_ASSERT(m_object != nullptr);
12927
12928 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12929 {
12930 return m_it.object_iterator->first;
12931 }
12932
12933 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
12934 }
12935
12941 {
12942 return operator*();
12943 }
12944
12947 pointer m_object = nullptr;
12950 };
12951 } // namespace detail
12952} // namespace nlohmann
12953
12954// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12955
12956// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12957
12958
12959#include <cstddef> // ptrdiff_t
12960#include <iterator> // reverse_iterator
12961#include <utility> // declval
12962
12963namespace nlohmann
12964{
12965 namespace detail
12966 {
12968 // reverse_iterator //
12970
12989 template<typename Base>
12990 class json_reverse_iterator : public std::reverse_iterator<Base>
12991 {
12992 public:
12993 using difference_type = std::ptrdiff_t;
12995 using base_iterator = std::reverse_iterator<Base>;
12997 using reference = typename Base::reference;
12998
13000 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13001 : base_iterator(it) {}
13002
13004 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13005
13007 json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13008 {
13009 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13010 }
13011
13014 {
13015 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13016 }
13017
13019 json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13020 {
13021 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13022 }
13023
13026 {
13027 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13028 }
13029
13032 {
13033 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13034 }
13035
13038 {
13039 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13040 }
13041
13044 {
13045 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13046 }
13047
13050 {
13051 return base_iterator(*this) - base_iterator(other);
13052 }
13053
13056 {
13057 return *(this->operator+(n));
13058 }
13059
13061 auto key() const -> decltype(std::declval<Base>().key())
13062 {
13063 auto it = --this->base();
13064 return it.key();
13065 }
13066
13069 {
13070 auto it = --this->base();
13071 return it.operator * ();
13072 }
13073 };
13074 } // namespace detail
13075} // namespace nlohmann
13076
13077// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13078
13079// #include <nlohmann/detail/json_pointer.hpp>
13080
13081
13082#include <algorithm> // all_of
13083#include <cctype> // isdigit
13084#include <cerrno> // errno, ERANGE
13085#include <cstdlib> // strtoull
13086#include <limits> // max
13087#include <numeric> // accumulate
13088#include <string> // string
13089#include <utility> // move
13090#include <vector> // vector
13091
13092// #include <nlohmann/detail/exceptions.hpp>
13093
13094// #include <nlohmann/detail/macro_scope.hpp>
13095
13096// #include <nlohmann/detail/string_concat.hpp>
13097
13098// #include <nlohmann/detail/string_escape.hpp>
13099
13100// #include <nlohmann/detail/value_t.hpp>
13101
13102
13103namespace nlohmann
13104{
13105
13108 template<typename RefStringType>
13110 {
13111 // allow basic_json to access private members
13113 friend class basic_json;
13114
13115 template<typename>
13116 friend class json_pointer;
13117
13118 template<typename T>
13119 struct string_t_helper
13120 {
13121 using type = T;
13122 };
13123
13125 struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
13126 {
13127 using type = StringType;
13128 };
13129
13130 public:
13131 // for backwards compatibility accept BasicJsonType
13132 using string_t = typename string_t_helper<RefStringType>::type;
13133
13136 explicit json_pointer(const string_t& s = "")
13137 : reference_tokens(split(s))
13138 {}
13139
13143 {
13144 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13145 string_t{},
13146 [](const string_t& a, const string_t& b)
13147 {
13148 return detail::concat(a, '/', detail::escape(b));
13149 });
13150 }
13151
13154 operator string_t() const
13155 {
13156 return to_string();
13157 }
13158
13162 {
13163 reference_tokens.insert(reference_tokens.end(),
13164 ptr.reference_tokens.begin(),
13165 ptr.reference_tokens.end());
13166 return *this;
13167 }
13168
13172 {
13173 push_back(std::move(token));
13174 return *this;
13175 }
13176
13179 json_pointer& operator/=(std::size_t array_idx)
13180 {
13181 return *this /= std::to_string(array_idx);
13182 }
13183
13187 const json_pointer& rhs)
13188 {
13189 return json_pointer(lhs) /= rhs;
13190 }
13191
13194 friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13195 {
13196 return json_pointer(lhs) /= std::move(token);
13197 }
13198
13201 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13202 {
13203 return json_pointer(lhs) /= array_idx;
13204 }
13205
13209 {
13210 if (empty())
13211 {
13212 return *this;
13213 }
13214
13215 json_pointer res = *this;
13216 res.pop_back();
13217 return res;
13218 }
13219
13223 {
13225 {
13226 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13227 }
13228
13229 reference_tokens.pop_back();
13230 }
13231
13234 const string_t& back() const
13235 {
13237 {
13238 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13239 }
13240
13241 return reference_tokens.back();
13242 }
13243
13246 void push_back(const string_t& token)
13247 {
13248 reference_tokens.push_back(token);
13249 }
13250
13253 void push_back(string_t&& token)
13254 {
13255 reference_tokens.push_back(std::move(token));
13256 }
13257
13260 bool empty() const noexcept
13261 {
13262 return reference_tokens.empty();
13263 }
13264
13265 private:
13276 template<typename BasicJsonType>
13277 static typename BasicJsonType::size_type array_index(const string_t& s)
13278 {
13279 using size_type = typename BasicJsonType::size_type;
13280
13281 // error condition (cf. RFC 6901, Sect. 4)
13282 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13283 {
13284 JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13285 }
13286
13287 // error condition (cf. RFC 6901, Sect. 4)
13288 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13289 {
13290 JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13291 }
13292
13293 const char* p = s.c_str();
13294 char* p_end = nullptr;
13295 errno = 0; // strtoull doesn't reset errno
13296 unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13297 if (p == p_end // invalid input or empty string
13298 || errno == ERANGE // out of range
13299 || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13300 {
13301 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13302 }
13303
13304 // only triggered on special platforms (like 32bit), see also
13305 // https://github.com/nlohmann/json/pull/2203
13306 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13307 {
13308 JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13309 }
13310
13311 return static_cast<size_type>(res);
13312 }
13313
13315 json_pointer top() const
13316 {
13318 {
13319 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13320 }
13321
13322 json_pointer result = *this;
13323 result.reference_tokens = { reference_tokens[0] };
13324 return result;
13325 }
13326
13327 private:
13336 template<typename BasicJsonType>
13337 BasicJsonType& get_and_create(BasicJsonType& j) const
13338 {
13339 auto* result = &j;
13340
13341 // in case no reference tokens exist, return a reference to the JSON value
13342 // j which will be overwritten by a primitive value
13343 for (const auto& reference_token : reference_tokens)
13344 {
13345 switch (result->type())
13346 {
13348 {
13349 if (reference_token == "0")
13350 {
13351 // start a new array if reference token is 0
13352 result = &result->operator[](0);
13353 }
13354 else
13355 {
13356 // start a new object otherwise
13357 result = &result->operator[](reference_token);
13358 }
13359 break;
13360 }
13361
13363 {
13364 // create an entry in the object
13365 result = &result->operator[](reference_token);
13366 break;
13367 }
13368
13370 {
13371 // create an entry in the array
13372 result = &result->operator[](array_index<BasicJsonType>(reference_token));
13373 break;
13374 }
13375
13376 /*
13377 The following code is only reached if there exists a reference
13378 token _and_ the current value is primitive. In this case, we have
13379 an error situation, because primitive values may only occur as
13380 single value; that is, with an empty list of reference tokens.
13381 */
13389 default:
13390 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
13391 }
13392 }
13393
13394 return *result;
13395 }
13396
13416 template<typename BasicJsonType>
13417 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
13418 {
13419 for (const auto& reference_token : reference_tokens)
13420 {
13421 // convert null values to arrays or objects before continuing
13422 if (ptr->is_null())
13423 {
13424 // check if reference token is a number
13425 const bool nums =
13426 std::all_of(reference_token.begin(), reference_token.end(),
13427 [](const unsigned char x)
13428 {
13429 return std::isdigit(x);
13430 });
13431
13432 // change value to array for numbers or "-" or to object otherwise
13433 *ptr = (nums || reference_token == "-")
13436 }
13437
13438 switch (ptr->type())
13439 {
13441 {
13442 // use unchecked object access
13443 ptr = &ptr->operator[](reference_token);
13444 break;
13445 }
13446
13448 {
13449 if (reference_token == "-")
13450 {
13451 // explicitly treat "-" as index beyond the end
13452 ptr = &ptr->operator[](ptr->m_value.array->size());
13453 }
13454 else
13455 {
13456 // convert array index to number; unchecked access
13457 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13458 }
13459 break;
13460 }
13461
13470 default:
13471 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13472 }
13473 }
13474
13475 return *ptr;
13476 }
13477
13484 template<typename BasicJsonType>
13485 BasicJsonType& get_checked(BasicJsonType* ptr) const
13486 {
13487 for (const auto& reference_token : reference_tokens)
13488 {
13489 switch (ptr->type())
13490 {
13492 {
13493 // note: at performs range check
13494 ptr = &ptr->at(reference_token);
13495 break;
13496 }
13497
13499 {
13500 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13501 {
13502 // "-" always fails the range check
13504 "array index '-' (", std::to_string(ptr->m_value.array->size()),
13505 ") is out of range"), ptr));
13506 }
13507
13508 // note: at performs range check
13509 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13510 break;
13511 }
13512
13521 default:
13522 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13523 }
13524 }
13525
13526 return *ptr;
13527 }
13528
13542 template<typename BasicJsonType>
13543 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13544 {
13545 for (const auto& reference_token : reference_tokens)
13546 {
13547 switch (ptr->type())
13548 {
13550 {
13551 // use unchecked object access
13552 ptr = &ptr->operator[](reference_token);
13553 break;
13554 }
13555
13557 {
13558 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13559 {
13560 // "-" cannot be used for const access
13561 JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
13562 }
13563
13564 // use unchecked array access
13565 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13566 break;
13567 }
13568
13577 default:
13578 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13579 }
13580 }
13581
13582 return *ptr;
13583 }
13584
13591 template<typename BasicJsonType>
13592 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13593 {
13594 for (const auto& reference_token : reference_tokens)
13595 {
13596 switch (ptr->type())
13597 {
13599 {
13600 // note: at performs range check
13601 ptr = &ptr->at(reference_token);
13602 break;
13603 }
13604
13606 {
13607 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13608 {
13609 // "-" always fails the range check
13611 "array index '-' (", std::to_string(ptr->m_value.array->size()),
13612 ") is out of range"), ptr));
13613 }
13614
13615 // note: at performs range check
13616 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13617 break;
13618 }
13619
13628 default:
13629 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13630 }
13631 }
13632
13633 return *ptr;
13634 }
13635
13640 template<typename BasicJsonType>
13641 bool contains(const BasicJsonType* ptr) const
13642 {
13643 for (const auto& reference_token : reference_tokens)
13644 {
13645 switch (ptr->type())
13646 {
13648 {
13649 if (!ptr->contains(reference_token))
13650 {
13651 // we did not find the key in the object
13652 return false;
13653 }
13654
13655 ptr = &ptr->operator[](reference_token);
13656 break;
13657 }
13658
13660 {
13661 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13662 {
13663 // "-" always fails the range check
13664 return false;
13665 }
13666 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13667 {
13668 // invalid char
13669 return false;
13670 }
13671 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13672 {
13673 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13674 {
13675 // first char should be between '1' and '9'
13676 return false;
13677 }
13678 for (std::size_t i = 1; i < reference_token.size(); i++)
13679 {
13680 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13681 {
13682 // other char should be between '0' and '9'
13683 return false;
13684 }
13685 }
13686 }
13687
13688 const auto idx = array_index<BasicJsonType>(reference_token);
13689 if (idx >= ptr->size())
13690 {
13691 // index out of range
13692 return false;
13693 }
13694
13695 ptr = &ptr->operator[](idx);
13696 break;
13697 }
13698
13707 default:
13708 {
13709 // we do not expect primitive values if there is still a
13710 // reference token to process
13711 return false;
13712 }
13713 }
13714 }
13715
13716 // no reference token left means we found a primitive value
13717 return true;
13718 }
13719
13729 static std::vector<string_t> split(const string_t& reference_string)
13730 {
13731 std::vector<string_t> result;
13732
13733 // special case: empty reference string -> no reference tokens
13734 if (reference_string.empty())
13735 {
13736 return result;
13737 }
13738
13739 // check if nonempty reference string begins with slash
13740 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13741 {
13742 JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
13743 }
13744
13745 // extract the reference tokens:
13746 // - slash: position of the last read slash (or end of string)
13747 // - start: position after the previous slash
13748 for (
13749 // search for the first slash after the first character
13750 std::size_t slash = reference_string.find_first_of('/', 1),
13751 // set the beginning of the first reference token
13752 start = 1;
13753 // we can stop if start == 0 (if slash == string_t::npos)
13754 start != 0;
13755 // set the beginning of the next reference token
13756 // (will eventually be 0 if slash == string_t::npos)
13757 start = (slash == string_t::npos) ? 0 : slash + 1,
13758 // find next slash
13759 slash = reference_string.find_first_of('/', start))
13760 {
13761 // use the text between the beginning of the reference token
13762 // (start) and the last slash (slash).
13763 auto reference_token = reference_string.substr(start, slash - start);
13764
13765 // check reference tokens are properly escaped
13766 for (std::size_t pos = reference_token.find_first_of('~');
13767 pos != string_t::npos;
13768 pos = reference_token.find_first_of('~', pos + 1))
13769 {
13770 JSON_ASSERT(reference_token[pos] == '~');
13771
13772 // ~ must be followed by 0 or 1
13773 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13774 (reference_token[pos + 1] != '0' &&
13775 reference_token[pos + 1] != '1')))
13776 {
13777 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
13778 }
13779 }
13780
13781 // finally, store the reference token
13782 detail::unescape(reference_token);
13783 result.push_back(reference_token);
13784 }
13785
13786 return result;
13787 }
13788
13789 private:
13797 template<typename BasicJsonType>
13798 static void flatten(const string_t& reference_string,
13799 const BasicJsonType& value,
13800 BasicJsonType& result)
13801 {
13802 switch (value.type())
13803 {
13805 {
13806 if (value.m_value.array->empty())
13807 {
13808 // flatten empty array as null
13809 result[reference_string] = nullptr;
13810 }
13811 else
13812 {
13813 // iterate array and use index as reference string
13814 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13815 {
13816 flatten(detail::concat(reference_string, '/', std::to_string(i)),
13817 value.m_value.array->operator[](i), result);
13818 }
13819 }
13820 break;
13821 }
13822
13824 {
13825 if (value.m_value.object->empty())
13826 {
13827 // flatten empty object as null
13828 result[reference_string] = nullptr;
13829 }
13830 else
13831 {
13832 // iterate object and use keys as reference string
13833 for (const auto& element : *value.m_value.object)
13834 {
13835 flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
13836 }
13837 }
13838 break;
13839 }
13840
13849 default:
13850 {
13851 // add primitive value with its reference string
13852 result[reference_string] = value;
13853 break;
13854 }
13855 }
13856 }
13857
13868 template<typename BasicJsonType>
13869 static BasicJsonType
13870 unflatten(const BasicJsonType& value)
13871 {
13872 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13873 {
13874 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
13875 }
13876
13877 BasicJsonType result;
13878
13879 // iterate the JSON object values
13880 for (const auto& element : *value.m_value.object)
13881 {
13882 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13883 {
13884 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
13885 }
13886
13887 // assign value to reference pointed to by JSON pointer; Note that if
13888 // the JSON pointer is "" (i.e., points to the whole value), function
13889 // get_and_create returns a reference to result itself. An assignment
13890 // will then create a primitive value.
13891 json_pointer(element.first).get_and_create(result) = element.second;
13892 }
13893
13894 return result;
13895 }
13896
13897 // can't use conversion operator because of ambiguity
13898 json_pointer<string_t> convert() const&
13899 {
13900 json_pointer<string_t> result;
13901 result.reference_tokens = reference_tokens;
13902 return result;
13903 }
13904
13905 json_pointer<string_t> convert()&&
13906 {
13907 json_pointer<string_t> result;
13908 result.reference_tokens = std::move(reference_tokens);
13909 return result;
13910 }
13911
13923 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13924 // NOLINTNEXTLINE(readability-redundant-declaration)
13925 friend bool operator==(json_pointer<RefStringTypeLhs> const& lhs,
13926 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
13927
13939 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13940 // NOLINTNEXTLINE(readability-redundant-declaration)
13941 friend bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
13942 json_pointer<RefStringTypeRhs> const& rhs) noexcept;
13943
13945 std::vector<string_t> reference_tokens;
13946 };
13947
13948 // functions cannot be defined inside class due to ODR violations
13949 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13951 json_pointer<RefStringTypeRhs> const& rhs) noexcept
13952 {
13953 return lhs.reference_tokens == rhs.reference_tokens;
13954 }
13955
13956 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
13958 json_pointer<RefStringTypeRhs> const& rhs) noexcept
13959 {
13960 return !(lhs == rhs);
13961 }
13962} // namespace nlohmann
13963
13964// #include <nlohmann/detail/json_ref.hpp>
13965
13966
13967#include <initializer_list>
13968#include <utility>
13969
13970// #include <nlohmann/detail/meta/type_traits.hpp>
13971
13972
13973namespace nlohmann
13974{
13975 namespace detail
13976 {
13977 template<typename BasicJsonType>
13979 {
13980 public:
13981 using value_type = BasicJsonType;
13982
13984 : owned_value(std::move(value))
13985 {}
13986
13987 json_ref(const value_type& value)
13988 : value_ref(&value)
13989 {}
13990
13991 json_ref(std::initializer_list<json_ref> init)
13992 : owned_value(init)
13993 {}
13994
13995 template <
13996 class... Args,
13997 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13998 json_ref(Args && ... args)
13999 : owned_value(std::forward<Args>(args)...)
14000 {}
14001
14002 // class should be movable only
14003 json_ref(json_ref&&) noexcept = default;
14004 json_ref(const json_ref&) = delete;
14005 json_ref& operator=(const json_ref&) = delete;
14006 json_ref& operator=(json_ref&&) = delete;
14007 ~json_ref() = default;
14008
14010 {
14011 if (value_ref == nullptr)
14012 {
14013 return std::move(owned_value);
14014 }
14015 return *value_ref;
14016 }
14017
14018 value_type const& operator*() const
14019 {
14020 return value_ref ? *value_ref : owned_value;
14021 }
14022
14023 value_type const* operator->() const
14024 {
14025 return &**this;
14026 }
14027
14028 private:
14029 mutable value_type owned_value = nullptr;
14030 value_type const* value_ref = nullptr;
14031 };
14032 } // namespace detail
14033} // namespace nlohmann
14034
14035// #include <nlohmann/detail/macro_scope.hpp>
14036
14037// #include <nlohmann/detail/string_concat.hpp>
14038
14039// #include <nlohmann/detail/string_escape.hpp>
14040
14041// #include <nlohmann/detail/meta/cpp_future.hpp>
14042
14043// #include <nlohmann/detail/meta/type_traits.hpp>
14044
14045// #include <nlohmann/detail/output/binary_writer.hpp>
14046
14047
14048#include <algorithm> // reverse
14049#include <array> // array
14050#include <map> // map
14051#include <cmath> // isnan, isinf
14052#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14053#include <cstring> // memcpy
14054#include <limits> // numeric_limits
14055#include <string> // string
14056#include <utility> // move
14057#include <vector> // vector
14058
14059// #include <nlohmann/detail/input/binary_reader.hpp>
14060
14061// #include <nlohmann/detail/macro_scope.hpp>
14062
14063// #include <nlohmann/detail/output/output_adapters.hpp>
14064
14065
14066#include <algorithm> // copy
14067#include <cstddef> // size_t
14068#include <iterator> // back_inserter
14069#include <memory> // shared_ptr, make_shared
14070#include <string> // basic_string
14071#include <vector> // vector
14072
14073#ifndef JSON_NO_IO
14074#include <ios> // streamsize
14075#include <ostream> // basic_ostream
14076#endif // JSON_NO_IO
14077
14078// #include <nlohmann/detail/macro_scope.hpp>
14079
14080
14081namespace nlohmann
14082{
14083 namespace detail
14084 {
14086 template<typename CharType> struct output_adapter_protocol
14087 {
14088 virtual void write_character(CharType c) = 0;
14089 virtual void write_characters(const CharType* s, std::size_t length) = 0;
14090 virtual ~output_adapter_protocol() = default;
14091
14096 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14097 };
14098
14100 template<typename CharType>
14101 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14102
14104 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14106 {
14107 public:
14108 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14109 : v(vec)
14110 {}
14111
14112 void write_character(CharType c) override
14113 {
14114 v.push_back(c);
14115 }
14116
14118 void write_characters(const CharType* s, std::size_t length) override
14119 {
14120 std::copy(s, s + length, std::back_inserter(v));
14121 }
14122
14123 private:
14124 std::vector<CharType, AllocatorType>& v;
14125 };
14126
14127#ifndef JSON_NO_IO
14129 template<typename CharType>
14131 {
14132 public:
14133 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14134 : stream(s)
14135 {}
14136
14137 void write_character(CharType c) override
14138 {
14139 stream.put(c);
14140 }
14141
14143 void write_characters(const CharType* s, std::size_t length) override
14144 {
14145 stream.write(s, static_cast<std::streamsize>(length));
14146 }
14147
14148 private:
14149 std::basic_ostream<CharType>& stream;
14150 };
14151#endif // JSON_NO_IO
14152
14154 template<typename CharType, typename StringType = std::basic_string<CharType>>
14156 {
14157 public:
14158 explicit output_string_adapter(StringType& s) noexcept
14159 : str(s)
14160 {}
14161
14162 void write_character(CharType c) override
14163 {
14164 str.push_back(c);
14165 }
14166
14168 void write_characters(const CharType* s, std::size_t length) override
14169 {
14170 str.append(s, length);
14171 }
14172
14173 private:
14174 StringType& str;
14175 };
14176
14177 template<typename CharType, typename StringType = std::basic_string<CharType>>
14179 {
14180 public:
14181 template<typename AllocatorType = std::allocator<CharType>>
14182 output_adapter(std::vector<CharType, AllocatorType>& vec)
14183 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14184
14185#ifndef JSON_NO_IO
14186 output_adapter(std::basic_ostream<CharType>& s)
14187 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14188#endif // JSON_NO_IO
14189
14190 output_adapter(StringType& s)
14191 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14192
14194 {
14195 return oa;
14196 }
14197
14198 private:
14199 output_adapter_t<CharType> oa = nullptr;
14200 };
14201 } // namespace detail
14202} // namespace nlohmann
14203
14204// #include <nlohmann/detail/string_concat.hpp>
14205
14206
14207namespace nlohmann
14208{
14209 namespace detail
14210 {
14212 // binary writer //
14214
14218 template<typename BasicJsonType, typename CharType>
14220 {
14221 using string_t = typename BasicJsonType::string_t;
14222 using binary_t = typename BasicJsonType::binary_t;
14223 using number_float_t = typename BasicJsonType::number_float_t;
14224
14225 public:
14231 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14232 {
14233 JSON_ASSERT(oa);
14234 }
14235
14240 void write_bson(const BasicJsonType& j)
14241 {
14242 switch (j.type())
14243 {
14244 case value_t::object:
14245 {
14246 write_bson_object(*j.m_value.object);
14247 break;
14248 }
14249
14250 case value_t::null:
14251 case value_t::array:
14252 case value_t::string:
14253 case value_t::boolean:
14254 case value_t::number_integer:
14255 case value_t::number_unsigned:
14256 case value_t::number_float:
14257 case value_t::binary:
14258 case value_t::discarded:
14259 default:
14260 {
14261 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
14262 }
14263 }
14264 }
14265
14269 void write_cbor(const BasicJsonType& j)
14270 {
14271 switch (j.type())
14272 {
14273 case value_t::null:
14274 {
14275 oa->write_character(to_char_type(0xF6));
14276 break;
14277 }
14278
14279 case value_t::boolean:
14280 {
14281 oa->write_character(j.m_value.boolean
14282 ? to_char_type(0xF5)
14283 : to_char_type(0xF4));
14284 break;
14285 }
14286
14287 case value_t::number_integer:
14288 {
14289 if (j.m_value.number_integer >= 0)
14290 {
14291 // CBOR does not differentiate between positive signed
14292 // integers and unsigned integers. Therefore, we used the
14293 // code from the value_t::number_unsigned case here.
14294 if (j.m_value.number_integer <= 0x17)
14295 {
14296 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14297 }
14298 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14299 {
14300 oa->write_character(to_char_type(0x18));
14301 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14302 }
14303 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
14304 {
14305 oa->write_character(to_char_type(0x19));
14306 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14307 }
14308 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
14309 {
14310 oa->write_character(to_char_type(0x1A));
14311 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14312 }
14313 else
14314 {
14315 oa->write_character(to_char_type(0x1B));
14316 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14317 }
14318 }
14319 else
14320 {
14321 // The conversions below encode the sign in the first
14322 // byte, and the value is converted to a positive number.
14323 const auto positive_number = -1 - j.m_value.number_integer;
14324 if (j.m_value.number_integer >= -24)
14325 {
14326 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
14327 }
14328 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
14329 {
14330 oa->write_character(to_char_type(0x38));
14331 write_number(static_cast<std::uint8_t>(positive_number));
14332 }
14333 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
14334 {
14335 oa->write_character(to_char_type(0x39));
14336 write_number(static_cast<std::uint16_t>(positive_number));
14337 }
14338 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
14339 {
14340 oa->write_character(to_char_type(0x3A));
14341 write_number(static_cast<std::uint32_t>(positive_number));
14342 }
14343 else
14344 {
14345 oa->write_character(to_char_type(0x3B));
14346 write_number(static_cast<std::uint64_t>(positive_number));
14347 }
14348 }
14349 break;
14350 }
14351
14352 case value_t::number_unsigned:
14353 {
14354 if (j.m_value.number_unsigned <= 0x17)
14355 {
14356 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14357 }
14358 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14359 {
14360 oa->write_character(to_char_type(0x18));
14361 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14362 }
14363 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14364 {
14365 oa->write_character(to_char_type(0x19));
14366 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
14367 }
14368 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14369 {
14370 oa->write_character(to_char_type(0x1A));
14371 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
14372 }
14373 else
14374 {
14375 oa->write_character(to_char_type(0x1B));
14376 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
14377 }
14378 break;
14379 }
14380
14381 case value_t::number_float:
14382 {
14383 if (std::isnan(j.m_value.number_float))
14384 {
14385 // NaN is 0xf97e00 in CBOR
14386 oa->write_character(to_char_type(0xF9));
14387 oa->write_character(to_char_type(0x7E));
14388 oa->write_character(to_char_type(0x00));
14389 }
14390 else if (std::isinf(j.m_value.number_float))
14391 {
14392 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
14393 oa->write_character(to_char_type(0xf9));
14394 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
14395 oa->write_character(to_char_type(0x00));
14396 }
14397 else
14398 {
14399 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
14400 }
14401 break;
14402 }
14403
14404 case value_t::string:
14405 {
14406 // step 1: write control byte and the string length
14407 const auto N = j.m_value.string->size();
14408 if (N <= 0x17)
14409 {
14410 write_number(static_cast<std::uint8_t>(0x60 + N));
14411 }
14412 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14413 {
14414 oa->write_character(to_char_type(0x78));
14415 write_number(static_cast<std::uint8_t>(N));
14416 }
14417 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14418 {
14419 oa->write_character(to_char_type(0x79));
14420 write_number(static_cast<std::uint16_t>(N));
14421 }
14422 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14423 {
14424 oa->write_character(to_char_type(0x7A));
14425 write_number(static_cast<std::uint32_t>(N));
14426 }
14427 // LCOV_EXCL_START
14428 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14429 {
14430 oa->write_character(to_char_type(0x7B));
14431 write_number(static_cast<std::uint64_t>(N));
14432 }
14433 // LCOV_EXCL_STOP
14434
14435 // step 2: write the string
14436 oa->write_characters(
14437 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14438 j.m_value.string->size());
14439 break;
14440 }
14441
14442 case value_t::array:
14443 {
14444 // step 1: write control byte and the array size
14445 const auto N = j.m_value.array->size();
14446 if (N <= 0x17)
14447 {
14448 write_number(static_cast<std::uint8_t>(0x80 + N));
14449 }
14450 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14451 {
14452 oa->write_character(to_char_type(0x98));
14453 write_number(static_cast<std::uint8_t>(N));
14454 }
14455 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14456 {
14457 oa->write_character(to_char_type(0x99));
14458 write_number(static_cast<std::uint16_t>(N));
14459 }
14460 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14461 {
14462 oa->write_character(to_char_type(0x9A));
14463 write_number(static_cast<std::uint32_t>(N));
14464 }
14465 // LCOV_EXCL_START
14466 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14467 {
14468 oa->write_character(to_char_type(0x9B));
14469 write_number(static_cast<std::uint64_t>(N));
14470 }
14471 // LCOV_EXCL_STOP
14472
14473 // step 2: write each element
14474 for (const auto& el : *j.m_value.array)
14475 {
14476 write_cbor(el);
14477 }
14478 break;
14479 }
14480
14481 case value_t::binary:
14482 {
14483 if (j.m_value.binary->has_subtype())
14484 {
14485 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
14486 {
14487 write_number(static_cast<std::uint8_t>(0xd8));
14488 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
14489 }
14490 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
14491 {
14492 write_number(static_cast<std::uint8_t>(0xd9));
14493 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
14494 }
14495 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
14496 {
14497 write_number(static_cast<std::uint8_t>(0xda));
14498 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
14499 }
14500 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
14501 {
14502 write_number(static_cast<std::uint8_t>(0xdb));
14503 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
14504 }
14505 }
14506
14507 // step 1: write control byte and the binary array size
14508 const auto N = j.m_value.binary->size();
14509 if (N <= 0x17)
14510 {
14511 write_number(static_cast<std::uint8_t>(0x40 + N));
14512 }
14513 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14514 {
14515 oa->write_character(to_char_type(0x58));
14516 write_number(static_cast<std::uint8_t>(N));
14517 }
14518 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14519 {
14520 oa->write_character(to_char_type(0x59));
14521 write_number(static_cast<std::uint16_t>(N));
14522 }
14523 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14524 {
14525 oa->write_character(to_char_type(0x5A));
14526 write_number(static_cast<std::uint32_t>(N));
14527 }
14528 // LCOV_EXCL_START
14529 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14530 {
14531 oa->write_character(to_char_type(0x5B));
14532 write_number(static_cast<std::uint64_t>(N));
14533 }
14534 // LCOV_EXCL_STOP
14535
14536 // step 2: write each element
14537 oa->write_characters(
14538 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14539 N);
14540
14541 break;
14542 }
14543
14544 case value_t::object:
14545 {
14546 // step 1: write control byte and the object size
14547 const auto N = j.m_value.object->size();
14548 if (N <= 0x17)
14549 {
14550 write_number(static_cast<std::uint8_t>(0xA0 + N));
14551 }
14552 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14553 {
14554 oa->write_character(to_char_type(0xB8));
14555 write_number(static_cast<std::uint8_t>(N));
14556 }
14557 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14558 {
14559 oa->write_character(to_char_type(0xB9));
14560 write_number(static_cast<std::uint16_t>(N));
14561 }
14562 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14563 {
14564 oa->write_character(to_char_type(0xBA));
14565 write_number(static_cast<std::uint32_t>(N));
14566 }
14567 // LCOV_EXCL_START
14568 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14569 {
14570 oa->write_character(to_char_type(0xBB));
14571 write_number(static_cast<std::uint64_t>(N));
14572 }
14573 // LCOV_EXCL_STOP
14574
14575 // step 2: write each element
14576 for (const auto& el : *j.m_value.object)
14577 {
14578 write_cbor(el.first);
14579 write_cbor(el.second);
14580 }
14581 break;
14582 }
14583
14584 case value_t::discarded:
14585 default:
14586 break;
14587 }
14588 }
14589
14593 void write_msgpack(const BasicJsonType& j)
14594 {
14595 switch (j.type())
14596 {
14597 case value_t::null: // nil
14598 {
14599 oa->write_character(to_char_type(0xC0));
14600 break;
14601 }
14602
14603 case value_t::boolean: // true and false
14604 {
14605 oa->write_character(j.m_value.boolean
14606 ? to_char_type(0xC3)
14607 : to_char_type(0xC2));
14608 break;
14609 }
14610
14611 case value_t::number_integer:
14612 {
14613 if (j.m_value.number_integer >= 0)
14614 {
14615 // MessagePack does not differentiate between positive
14616 // signed integers and unsigned integers. Therefore, we used
14617 // the code from the value_t::number_unsigned case here.
14618 if (j.m_value.number_unsigned < 128)
14619 {
14620 // positive fixnum
14621 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14622 }
14623 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14624 {
14625 // uint 8
14626 oa->write_character(to_char_type(0xCC));
14627 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14628 }
14629 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14630 {
14631 // uint 16
14632 oa->write_character(to_char_type(0xCD));
14633 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14634 }
14635 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14636 {
14637 // uint 32
14638 oa->write_character(to_char_type(0xCE));
14639 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14640 }
14641 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14642 {
14643 // uint 64
14644 oa->write_character(to_char_type(0xCF));
14645 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14646 }
14647 }
14648 else
14649 {
14650 if (j.m_value.number_integer >= -32)
14651 {
14652 // negative fixnum
14653 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14654 }
14655 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14656 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14657 {
14658 // int 8
14659 oa->write_character(to_char_type(0xD0));
14660 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14661 }
14662 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14663 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14664 {
14665 // int 16
14666 oa->write_character(to_char_type(0xD1));
14667 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14668 }
14669 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14670 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14671 {
14672 // int 32
14673 oa->write_character(to_char_type(0xD2));
14674 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14675 }
14676 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14677 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14678 {
14679 // int 64
14680 oa->write_character(to_char_type(0xD3));
14681 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14682 }
14683 }
14684 break;
14685 }
14686
14687 case value_t::number_unsigned:
14688 {
14689 if (j.m_value.number_unsigned < 128)
14690 {
14691 // positive fixnum
14692 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14693 }
14694 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14695 {
14696 // uint 8
14697 oa->write_character(to_char_type(0xCC));
14698 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14699 }
14700 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14701 {
14702 // uint 16
14703 oa->write_character(to_char_type(0xCD));
14704 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14705 }
14706 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14707 {
14708 // uint 32
14709 oa->write_character(to_char_type(0xCE));
14710 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14711 }
14712 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14713 {
14714 // uint 64
14715 oa->write_character(to_char_type(0xCF));
14716 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14717 }
14718 break;
14719 }
14720
14721 case value_t::number_float:
14722 {
14723 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14724 break;
14725 }
14726
14727 case value_t::string:
14728 {
14729 // step 1: write control byte and the string length
14730 const auto N = j.m_value.string->size();
14731 if (N <= 31)
14732 {
14733 // fixstr
14734 write_number(static_cast<std::uint8_t>(0xA0 | N));
14735 }
14736 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14737 {
14738 // str 8
14739 oa->write_character(to_char_type(0xD9));
14740 write_number(static_cast<std::uint8_t>(N));
14741 }
14742 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14743 {
14744 // str 16
14745 oa->write_character(to_char_type(0xDA));
14746 write_number(static_cast<std::uint16_t>(N));
14747 }
14748 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14749 {
14750 // str 32
14751 oa->write_character(to_char_type(0xDB));
14752 write_number(static_cast<std::uint32_t>(N));
14753 }
14754
14755 // step 2: write the string
14756 oa->write_characters(
14757 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14758 j.m_value.string->size());
14759 break;
14760 }
14761
14762 case value_t::array:
14763 {
14764 // step 1: write control byte and the array size
14765 const auto N = j.m_value.array->size();
14766 if (N <= 15)
14767 {
14768 // fixarray
14769 write_number(static_cast<std::uint8_t>(0x90 | N));
14770 }
14771 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14772 {
14773 // array 16
14774 oa->write_character(to_char_type(0xDC));
14775 write_number(static_cast<std::uint16_t>(N));
14776 }
14777 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14778 {
14779 // array 32
14780 oa->write_character(to_char_type(0xDD));
14781 write_number(static_cast<std::uint32_t>(N));
14782 }
14783
14784 // step 2: write each element
14785 for (const auto& el : *j.m_value.array)
14786 {
14787 write_msgpack(el);
14788 }
14789 break;
14790 }
14791
14792 case value_t::binary:
14793 {
14794 // step 0: determine if the binary type has a set subtype to
14795 // determine whether or not to use the ext or fixext types
14796 const bool use_ext = j.m_value.binary->has_subtype();
14797
14798 // step 1: write control byte and the byte string length
14799 const auto N = j.m_value.binary->size();
14800 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14801 {
14802 std::uint8_t output_type{};
14803 bool fixed = true;
14804 if (use_ext)
14805 {
14806 switch (N)
14807 {
14808 case 1:
14809 output_type = 0xD4; // fixext 1
14810 break;
14811 case 2:
14812 output_type = 0xD5; // fixext 2
14813 break;
14814 case 4:
14815 output_type = 0xD6; // fixext 4
14816 break;
14817 case 8:
14818 output_type = 0xD7; // fixext 8
14819 break;
14820 case 16:
14821 output_type = 0xD8; // fixext 16
14822 break;
14823 default:
14824 output_type = 0xC7; // ext 8
14825 fixed = false;
14826 break;
14827 }
14828
14829 }
14830 else
14831 {
14832 output_type = 0xC4; // bin 8
14833 fixed = false;
14834 }
14835
14836 oa->write_character(to_char_type(output_type));
14837 if (!fixed)
14838 {
14839 write_number(static_cast<std::uint8_t>(N));
14840 }
14841 }
14842 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14843 {
14844 std::uint8_t output_type = use_ext
14845 ? 0xC8 // ext 16
14846 : 0xC5; // bin 16
14847
14848 oa->write_character(to_char_type(output_type));
14849 write_number(static_cast<std::uint16_t>(N));
14850 }
14851 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14852 {
14853 std::uint8_t output_type = use_ext
14854 ? 0xC9 // ext 32
14855 : 0xC6; // bin 32
14856
14857 oa->write_character(to_char_type(output_type));
14858 write_number(static_cast<std::uint32_t>(N));
14859 }
14860
14861 // step 1.5: if this is an ext type, write the subtype
14862 if (use_ext)
14863 {
14864 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14865 }
14866
14867 // step 2: write the byte string
14868 oa->write_characters(
14869 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14870 N);
14871
14872 break;
14873 }
14874
14875 case value_t::object:
14876 {
14877 // step 1: write control byte and the object size
14878 const auto N = j.m_value.object->size();
14879 if (N <= 15)
14880 {
14881 // fixmap
14882 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14883 }
14884 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14885 {
14886 // map 16
14887 oa->write_character(to_char_type(0xDE));
14888 write_number(static_cast<std::uint16_t>(N));
14889 }
14890 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14891 {
14892 // map 32
14893 oa->write_character(to_char_type(0xDF));
14894 write_number(static_cast<std::uint32_t>(N));
14895 }
14896
14897 // step 2: write each element
14898 for (const auto& el : *j.m_value.object)
14899 {
14900 write_msgpack(el.first);
14901 write_msgpack(el.second);
14902 }
14903 break;
14904 }
14905
14906 case value_t::discarded:
14907 default:
14908 break;
14909 }
14910 }
14911
14919 void write_ubjson(const BasicJsonType& j, const bool use_count,
14920 const bool use_type, const bool add_prefix = true,
14921 const bool use_bjdata = false)
14922 {
14923 switch (j.type())
14924 {
14925 case value_t::null:
14926 {
14927 if (add_prefix)
14928 {
14929 oa->write_character(to_char_type('Z'));
14930 }
14931 break;
14932 }
14933
14934 case value_t::boolean:
14935 {
14936 if (add_prefix)
14937 {
14938 oa->write_character(j.m_value.boolean
14939 ? to_char_type('T')
14940 : to_char_type('F'));
14941 }
14942 break;
14943 }
14944
14945 case value_t::number_integer:
14946 {
14947 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
14948 break;
14949 }
14950
14951 case value_t::number_unsigned:
14952 {
14953 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
14954 break;
14955 }
14956
14957 case value_t::number_float:
14958 {
14959 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
14960 break;
14961 }
14962
14963 case value_t::string:
14964 {
14965 if (add_prefix)
14966 {
14967 oa->write_character(to_char_type('S'));
14968 }
14969 write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
14970 oa->write_characters(
14971 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14972 j.m_value.string->size());
14973 break;
14974 }
14975
14976 case value_t::array:
14977 {
14978 if (add_prefix)
14979 {
14980 oa->write_character(to_char_type('['));
14981 }
14982
14983 bool prefix_required = true;
14984 if (use_type && !j.m_value.array->empty())
14985 {
14986 JSON_ASSERT(use_count);
14987 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
14988 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14989 [this, first_prefix, use_bjdata](const BasicJsonType& v)
14990 {
14991 return ubjson_prefix(v, use_bjdata) == first_prefix;
14992 });
14993
14994 std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
14995
14996 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
14997 {
14998 prefix_required = false;
14999 oa->write_character(to_char_type('$'));
15000 oa->write_character(first_prefix);
15001 }
15002 }
15003
15004 if (use_count)
15005 {
15006 oa->write_character(to_char_type('#'));
15007 write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
15008 }
15009
15010 for (const auto& el : *j.m_value.array)
15011 {
15012 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15013 }
15014
15015 if (!use_count)
15016 {
15017 oa->write_character(to_char_type(']'));
15018 }
15019
15020 break;
15021 }
15022
15023 case value_t::binary:
15024 {
15025 if (add_prefix)
15026 {
15027 oa->write_character(to_char_type('['));
15028 }
15029
15030 if (use_type && !j.m_value.binary->empty())
15031 {
15032 JSON_ASSERT(use_count);
15033 oa->write_character(to_char_type('$'));
15034 oa->write_character('U');
15035 }
15036
15037 if (use_count)
15038 {
15039 oa->write_character(to_char_type('#'));
15040 write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
15041 }
15042
15043 if (use_type)
15044 {
15045 oa->write_characters(
15046 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15047 j.m_value.binary->size());
15048 }
15049 else
15050 {
15051 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
15052 {
15053 oa->write_character(to_char_type('U'));
15054 oa->write_character(j.m_value.binary->data()[i]);
15055 }
15056 }
15057
15058 if (!use_count)
15059 {
15060 oa->write_character(to_char_type(']'));
15061 }
15062
15063 break;
15064 }
15065
15066 case value_t::object:
15067 {
15068 if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
15069 {
15070 if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15071 {
15072 break;
15073 }
15074 }
15075
15076 if (add_prefix)
15077 {
15078 oa->write_character(to_char_type('{'));
15079 }
15080
15081 bool prefix_required = true;
15082 if (use_type && !j.m_value.object->empty())
15083 {
15084 JSON_ASSERT(use_count);
15085 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15086 const bool same_prefix = std::all_of(j.begin(), j.end(),
15087 [this, first_prefix, use_bjdata](const BasicJsonType& v)
15088 {
15089 return ubjson_prefix(v, use_bjdata) == first_prefix;
15090 });
15091
15092 std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
15093
15094 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15095 {
15096 prefix_required = false;
15097 oa->write_character(to_char_type('$'));
15098 oa->write_character(first_prefix);
15099 }
15100 }
15101
15102 if (use_count)
15103 {
15104 oa->write_character(to_char_type('#'));
15105 write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
15106 }
15107
15108 for (const auto& el : *j.m_value.object)
15109 {
15110 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15111 oa->write_characters(
15112 reinterpret_cast<const CharType*>(el.first.c_str()),
15113 el.first.size());
15114 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15115 }
15116
15117 if (!use_count)
15118 {
15119 oa->write_character(to_char_type('}'));
15120 }
15121
15122 break;
15123 }
15124
15125 case value_t::discarded:
15126 default:
15127 break;
15128 }
15129 }
15130
15131 private:
15133 // BSON //
15135
15140 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15141 {
15142 const auto it = name.find(static_cast<typename string_t::value_type>(0));
15143 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
15144 {
15145 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
15146 static_cast<void>(j);
15147 }
15148
15149 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
15150 }
15151
15155 void write_bson_entry_header(const string_t& name,
15156 const std::uint8_t element_type)
15157 {
15158 oa->write_character(to_char_type(element_type)); // boolean
15159 oa->write_characters(
15160 reinterpret_cast<const CharType*>(name.c_str()),
15161 name.size() + 1u);
15162 }
15163
15167 void write_bson_boolean(const string_t& name,
15168 const bool value)
15169 {
15170 write_bson_entry_header(name, 0x08);
15171 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15172 }
15173
15177 void write_bson_double(const string_t& name,
15178 const double value)
15179 {
15180 write_bson_entry_header(name, 0x01);
15181 write_number<double>(value, true);
15182 }
15183
15187 static std::size_t calc_bson_string_size(const string_t& value)
15188 {
15189 return sizeof(std::int32_t) + value.size() + 1ul;
15190 }
15191
15195 void write_bson_string(const string_t& name,
15196 const string_t& value)
15197 {
15198 write_bson_entry_header(name, 0x02);
15199
15200 write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15201 oa->write_characters(
15202 reinterpret_cast<const CharType*>(value.c_str()),
15203 value.size() + 1);
15204 }
15205
15209 void write_bson_null(const string_t& name)
15210 {
15211 write_bson_entry_header(name, 0x0A);
15212 }
15213
15217 static std::size_t calc_bson_integer_size(const std::int64_t value)
15218 {
15219 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15220 ? sizeof(std::int32_t)
15221 : sizeof(std::int64_t);
15222 }
15223
15227 void write_bson_integer(const string_t& name,
15228 const std::int64_t value)
15229 {
15230 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
15231 {
15232 write_bson_entry_header(name, 0x10); // int32
15233 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
15234 }
15235 else
15236 {
15237 write_bson_entry_header(name, 0x12); // int64
15238 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
15239 }
15240 }
15241
15245 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
15246 {
15247 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15248 ? sizeof(std::int32_t)
15249 : sizeof(std::int64_t);
15250 }
15251
15255 void write_bson_unsigned(const string_t& name,
15256 const BasicJsonType& j)
15257 {
15258 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15259 {
15260 write_bson_entry_header(name, 0x10 /* int32 */);
15261 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
15262 }
15263 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15264 {
15265 write_bson_entry_header(name, 0x12 /* int64 */);
15266 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
15267 }
15268 else
15269 {
15270 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
15271 }
15272 }
15273
15277 void write_bson_object_entry(const string_t& name,
15278 const typename BasicJsonType::object_t& value)
15279 {
15280 write_bson_entry_header(name, 0x03); // object
15281 write_bson_object(value);
15282 }
15283
15287 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
15288 {
15289 std::size_t array_index = 0ul;
15290
15291 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type& el)
15292 {
15293 return result + calc_bson_element_size(std::to_string(array_index++), el);
15294 });
15295
15296 return sizeof(std::int32_t) + embedded_document_size + 1ul;
15297 }
15298
15302 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
15303 {
15304 return sizeof(std::int32_t) + value.size() + 1ul;
15305 }
15306
15310 void write_bson_array(const string_t& name,
15311 const typename BasicJsonType::array_t& value)
15312 {
15313 write_bson_entry_header(name, 0x04); // array
15314 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
15315
15316 std::size_t array_index = 0ul;
15317
15318 for (const auto& el : value)
15319 {
15320 write_bson_element(std::to_string(array_index++), el);
15321 }
15322
15323 oa->write_character(to_char_type(0x00));
15324 }
15325
15329 void write_bson_binary(const string_t& name,
15330 const binary_t& value)
15331 {
15332 write_bson_entry_header(name, 0x05);
15333
15334 write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
15335 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
15336
15337 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
15338 }
15339
15344 static std::size_t calc_bson_element_size(const string_t& name,
15345 const BasicJsonType& j)
15346 {
15347 const auto header_size = calc_bson_entry_header_size(name, j);
15348 switch (j.type())
15349 {
15350 case value_t::object:
15351 return header_size + calc_bson_object_size(*j.m_value.object);
15352
15353 case value_t::array:
15354 return header_size + calc_bson_array_size(*j.m_value.array);
15355
15356 case value_t::binary:
15357 return header_size + calc_bson_binary_size(*j.m_value.binary);
15358
15359 case value_t::boolean:
15360 return header_size + 1ul;
15361
15362 case value_t::number_float:
15363 return header_size + 8ul;
15364
15365 case value_t::number_integer:
15366 return header_size + calc_bson_integer_size(j.m_value.number_integer);
15367
15368 case value_t::number_unsigned:
15369 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
15370
15371 case value_t::string:
15372 return header_size + calc_bson_string_size(*j.m_value.string);
15373
15374 case value_t::null:
15375 return header_size + 0ul;
15376
15377 // LCOV_EXCL_START
15378 case value_t::discarded:
15379 default:
15380 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15381 return 0ul;
15382 // LCOV_EXCL_STOP
15383 }
15384 }
15385
15392 void write_bson_element(const string_t& name,
15393 const BasicJsonType& j)
15394 {
15395 switch (j.type())
15396 {
15397 case value_t::object:
15398 return write_bson_object_entry(name, *j.m_value.object);
15399
15400 case value_t::array:
15401 return write_bson_array(name, *j.m_value.array);
15402
15403 case value_t::binary:
15404 return write_bson_binary(name, *j.m_value.binary);
15405
15406 case value_t::boolean:
15407 return write_bson_boolean(name, j.m_value.boolean);
15408
15409 case value_t::number_float:
15410 return write_bson_double(name, j.m_value.number_float);
15411
15412 case value_t::number_integer:
15413 return write_bson_integer(name, j.m_value.number_integer);
15414
15415 case value_t::number_unsigned:
15416 return write_bson_unsigned(name, j);
15417
15418 case value_t::string:
15419 return write_bson_string(name, *j.m_value.string);
15420
15421 case value_t::null:
15422 return write_bson_null(name);
15423
15424 // LCOV_EXCL_START
15425 case value_t::discarded:
15426 default:
15427 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15428 return;
15429 // LCOV_EXCL_STOP
15430 }
15431 }
15432
15439 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
15440 {
15441 std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
15442 [](size_t result, const typename BasicJsonType::object_t::value_type& el)
15443 {
15444 return result += calc_bson_element_size(el.first, el.second);
15445 });
15446
15447 return sizeof(std::int32_t) + document_size + 1ul;
15448 }
15449
15454 void write_bson_object(const typename BasicJsonType::object_t& value)
15455 {
15456 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
15457
15458 for (const auto& el : value)
15459 {
15460 write_bson_element(el.first, el.second);
15461 }
15462
15463 oa->write_character(to_char_type(0x00));
15464 }
15465
15467 // CBOR //
15469
15470 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
15471 {
15472 return to_char_type(0xFA); // Single-Precision Float
15473 }
15474
15475 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
15476 {
15477 return to_char_type(0xFB); // Double-Precision Float
15478 }
15479
15481 // MsgPack //
15483
15484 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
15485 {
15486 return to_char_type(0xCA); // float 32
15487 }
15488
15489 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
15490 {
15491 return to_char_type(0xCB); // float 64
15492 }
15493
15495 // UBJSON //
15497
15498 // UBJSON: write number (floating point)
15499 template<typename NumberType, typename std::enable_if<
15500 std::is_floating_point<NumberType>::value, int>::type = 0>
15501 void write_number_with_ubjson_prefix(const NumberType n,
15502 const bool add_prefix,
15503 const bool use_bjdata)
15504 {
15505 if (add_prefix)
15506 {
15507 oa->write_character(get_ubjson_float_prefix(n));
15508 }
15509 write_number(n, use_bjdata);
15510 }
15511
15512 // UBJSON: write number (unsigned integer)
15513 template<typename NumberType, typename std::enable_if<
15514 std::is_unsigned<NumberType>::value, int>::type = 0>
15515 void write_number_with_ubjson_prefix(const NumberType n,
15516 const bool add_prefix,
15517 const bool use_bjdata)
15518 {
15519 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15520 {
15521 if (add_prefix)
15522 {
15523 oa->write_character(to_char_type('i')); // int8
15524 }
15525 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15526 }
15527 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
15528 {
15529 if (add_prefix)
15530 {
15531 oa->write_character(to_char_type('U')); // uint8
15532 }
15533 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15534 }
15535 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15536 {
15537 if (add_prefix)
15538 {
15539 oa->write_character(to_char_type('I')); // int16
15540 }
15541 write_number(static_cast<std::int16_t>(n), use_bjdata);
15542 }
15543 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
15544 {
15545 if (add_prefix)
15546 {
15547 oa->write_character(to_char_type('u')); // uint16 - bjdata only
15548 }
15549 write_number(static_cast<std::uint16_t>(n), use_bjdata);
15550 }
15551 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15552 {
15553 if (add_prefix)
15554 {
15555 oa->write_character(to_char_type('l')); // int32
15556 }
15557 write_number(static_cast<std::int32_t>(n), use_bjdata);
15558 }
15559 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
15560 {
15561 if (add_prefix)
15562 {
15563 oa->write_character(to_char_type('m')); // uint32 - bjdata only
15564 }
15565 write_number(static_cast<std::uint32_t>(n), use_bjdata);
15566 }
15567 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15568 {
15569 if (add_prefix)
15570 {
15571 oa->write_character(to_char_type('L')); // int64
15572 }
15573 write_number(static_cast<std::int64_t>(n), use_bjdata);
15574 }
15575 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
15576 {
15577 if (add_prefix)
15578 {
15579 oa->write_character(to_char_type('M')); // uint64 - bjdata only
15580 }
15581 write_number(static_cast<std::uint64_t>(n), use_bjdata);
15582 }
15583 else
15584 {
15585 if (add_prefix)
15586 {
15587 oa->write_character(to_char_type('H')); // high-precision number
15588 }
15589
15590 const auto number = BasicJsonType(n).dump();
15591 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15592 for (std::size_t i = 0; i < number.size(); ++i)
15593 {
15594 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15595 }
15596 }
15597 }
15598
15599 // UBJSON: write number (signed integer)
15600 template < typename NumberType, typename std::enable_if <
15601 std::is_signed<NumberType>::value &&
15602 !std::is_floating_point<NumberType>::value, int >::type = 0 >
15603 void write_number_with_ubjson_prefix(const NumberType n,
15604 const bool add_prefix,
15605 const bool use_bjdata)
15606 {
15607 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15608 {
15609 if (add_prefix)
15610 {
15611 oa->write_character(to_char_type('i')); // int8
15612 }
15613 write_number(static_cast<std::int8_t>(n), use_bjdata);
15614 }
15615 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
15616 {
15617 if (add_prefix)
15618 {
15619 oa->write_character(to_char_type('U')); // uint8
15620 }
15621 write_number(static_cast<std::uint8_t>(n), use_bjdata);
15622 }
15623 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15624 {
15625 if (add_prefix)
15626 {
15627 oa->write_character(to_char_type('I')); // int16
15628 }
15629 write_number(static_cast<std::int16_t>(n), use_bjdata);
15630 }
15631 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
15632 {
15633 if (add_prefix)
15634 {
15635 oa->write_character(to_char_type('u')); // uint16 - bjdata only
15636 }
15637 write_number(static_cast<uint16_t>(n), use_bjdata);
15638 }
15639 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15640 {
15641 if (add_prefix)
15642 {
15643 oa->write_character(to_char_type('l')); // int32
15644 }
15645 write_number(static_cast<std::int32_t>(n), use_bjdata);
15646 }
15647 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
15648 {
15649 if (add_prefix)
15650 {
15651 oa->write_character(to_char_type('m')); // uint32 - bjdata only
15652 }
15653 write_number(static_cast<uint32_t>(n), use_bjdata);
15654 }
15655 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15656 {
15657 if (add_prefix)
15658 {
15659 oa->write_character(to_char_type('L')); // int64
15660 }
15661 write_number(static_cast<std::int64_t>(n), use_bjdata);
15662 }
15663 // LCOV_EXCL_START
15664 else
15665 {
15666 if (add_prefix)
15667 {
15668 oa->write_character(to_char_type('H')); // high-precision number
15669 }
15670
15671 const auto number = BasicJsonType(n).dump();
15672 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15673 for (std::size_t i = 0; i < number.size(); ++i)
15674 {
15675 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15676 }
15677 }
15678 // LCOV_EXCL_STOP
15679 }
15680
15684 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
15685 {
15686 switch (j.type())
15687 {
15688 case value_t::null:
15689 return 'Z';
15690
15691 case value_t::boolean:
15692 return j.m_value.boolean ? 'T' : 'F';
15693
15694 case value_t::number_integer:
15695 {
15696 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15697 {
15698 return 'i';
15699 }
15700 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15701 {
15702 return 'U';
15703 }
15704 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15705 {
15706 return 'I';
15707 }
15708 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
15709 {
15710 return 'u';
15711 }
15712 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15713 {
15714 return 'l';
15715 }
15716 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
15717 {
15718 return 'm';
15719 }
15720 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15721 {
15722 return 'L';
15723 }
15724 // anything else is treated as high-precision number
15725 return 'H'; // LCOV_EXCL_LINE
15726 }
15727
15728 case value_t::number_unsigned:
15729 {
15730 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15731 {
15732 return 'i';
15733 }
15734 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15735 {
15736 return 'U';
15737 }
15738 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15739 {
15740 return 'I';
15741 }
15742 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
15743 {
15744 return 'u';
15745 }
15746 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15747 {
15748 return 'l';
15749 }
15750 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
15751 {
15752 return 'm';
15753 }
15754 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15755 {
15756 return 'L';
15757 }
15758 if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15759 {
15760 return 'M';
15761 }
15762 // anything else is treated as high-precision number
15763 return 'H'; // LCOV_EXCL_LINE
15764 }
15765
15766 case value_t::number_float:
15767 return get_ubjson_float_prefix(j.m_value.number_float);
15768
15769 case value_t::string:
15770 return 'S';
15771
15772 case value_t::array: // fallthrough
15773 case value_t::binary:
15774 return '[';
15775
15776 case value_t::object:
15777 return '{';
15778
15779 case value_t::discarded:
15780 default: // discarded values
15781 return 'N';
15782 }
15783 }
15784
15785 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15786 {
15787 return 'd'; // float 32
15788 }
15789
15790 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15791 {
15792 return 'D'; // float 64
15793 }
15794
15798 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
15799 {
15800 std::map<string_t, CharType> bjdtype = { {"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
15801 {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
15802 };
15803
15804 string_t key = "_ArrayType_";
15805 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
15806 if (it == bjdtype.end())
15807 {
15808 return true;
15809 }
15810 CharType dtype = it->second;
15811
15812 key = "_ArraySize_";
15813 std::size_t len = (value.at(key).empty() ? 0 : 1);
15814 for (const auto& el : value.at(key))
15815 {
15816 len *= static_cast<std::size_t>(el.m_value.number_unsigned);
15817 }
15818
15819 key = "_ArrayData_";
15820 if (value.at(key).size() != len)
15821 {
15822 return true;
15823 }
15824
15825 oa->write_character('[');
15826 oa->write_character('$');
15827 oa->write_character(dtype);
15828 oa->write_character('#');
15829
15830 key = "_ArraySize_";
15831 write_ubjson(value.at(key), use_count, use_type, true, true);
15832
15833 key = "_ArrayData_";
15834 if (dtype == 'U' || dtype == 'C')
15835 {
15836 for (const auto& el : value.at(key))
15837 {
15838 write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
15839 }
15840 }
15841 else if (dtype == 'i')
15842 {
15843 for (const auto& el : value.at(key))
15844 {
15845 write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
15846 }
15847 }
15848 else if (dtype == 'u')
15849 {
15850 for (const auto& el : value.at(key))
15851 {
15852 write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
15853 }
15854 }
15855 else if (dtype == 'I')
15856 {
15857 for (const auto& el : value.at(key))
15858 {
15859 write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
15860 }
15861 }
15862 else if (dtype == 'm')
15863 {
15864 for (const auto& el : value.at(key))
15865 {
15866 write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
15867 }
15868 }
15869 else if (dtype == 'l')
15870 {
15871 for (const auto& el : value.at(key))
15872 {
15873 write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
15874 }
15875 }
15876 else if (dtype == 'M')
15877 {
15878 for (const auto& el : value.at(key))
15879 {
15880 write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
15881 }
15882 }
15883 else if (dtype == 'L')
15884 {
15885 for (const auto& el : value.at(key))
15886 {
15887 write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
15888 }
15889 }
15890 else if (dtype == 'd')
15891 {
15892 for (const auto& el : value.at(key))
15893 {
15894 write_number(static_cast<float>(el.m_value.number_float), true);
15895 }
15896 }
15897 else if (dtype == 'D')
15898 {
15899 for (const auto& el : value.at(key))
15900 {
15901 write_number(static_cast<double>(el.m_value.number_float), true);
15902 }
15903 }
15904 return false;
15905 }
15906
15908 // Utility functions //
15910
15911 /*
15912 @brief write a number to output input
15913 @param[in] n number of type @a NumberType
15914 @param[in] OutputIsLittleEndian Set to true if output data is
15915 required to be little endian
15916 @tparam NumberType the type of the number
15917
15918 @note This function needs to respect the system's endianness, because bytes
15919 in CBOR, MessagePack, and UBJSON are stored in network order (big
15920 endian) and therefore need reordering on little endian systems.
15921 On the other hand, BSON and BJData use little endian and should reorder
15922 on big endian systems.
15923 */
15924 template<typename NumberType>
15925 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
15926 {
15927 // step 1: write number to array of length NumberType
15928 std::array<CharType, sizeof(NumberType)> vec{};
15929 std::memcpy(vec.data(), &n, sizeof(NumberType));
15930
15931 // step 2: write array to output (with possible reordering)
15932 if (is_little_endian != OutputIsLittleEndian)
15933 {
15934 // reverse byte order prior to conversion if necessary
15935 std::reverse(vec.begin(), vec.end());
15936 }
15937
15938 oa->write_characters(vec.data(), sizeof(NumberType));
15939 }
15940
15941 void write_compact_float(const number_float_t n, detail::input_format_t format)
15942 {
15943#ifdef __GNUC__
15944#pragma GCC diagnostic push
15945#pragma GCC diagnostic ignored "-Wfloat-equal"
15946#endif
15947 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15948 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15949 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15950 {
15951 oa->write_character(format == detail::input_format_t::cbor
15952 ? get_cbor_float_prefix(static_cast<float>(n))
15953 : get_msgpack_float_prefix(static_cast<float>(n)));
15954 write_number(static_cast<float>(n));
15955 }
15956 else
15957 {
15958 oa->write_character(format == detail::input_format_t::cbor
15959 ? get_cbor_float_prefix(n)
15960 : get_msgpack_float_prefix(n));
15961 write_number(n);
15962 }
15963#ifdef __GNUC__
15964#pragma GCC diagnostic pop
15965#endif
15966 }
15967
15968 public:
15969 // The following to_char_type functions are implement the conversion
15970 // between uint8_t and CharType. In case CharType is not unsigned,
15971 // such a conversion is required to allow values greater than 128.
15972 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15973 template < typename C = CharType,
15974 enable_if_t < std::is_signed<C>::value&& std::is_signed<char>::value >* = nullptr >
15975 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15976 {
15977 return *reinterpret_cast<char*>(&x);
15978 }
15979
15980 template < typename C = CharType,
15981 enable_if_t < std::is_signed<C>::value&& std::is_unsigned<char>::value >* = nullptr >
15982 static CharType to_char_type(std::uint8_t x) noexcept
15983 {
15984 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15985 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15986 CharType result;
15987 std::memcpy(&result, &x, sizeof(x));
15988 return result;
15989 }
15990
15991 template<typename C = CharType,
15993 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15994 {
15995 return x;
15996 }
15997
15998 template < typename InputCharType, typename C = CharType,
15999 enable_if_t <
16000 std::is_signed<C>::value&&
16001 std::is_signed<char>::value&&
16002 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16003 >* = nullptr >
16004 static constexpr CharType to_char_type(InputCharType x) noexcept
16005 {
16006 return x;
16007 }
16008
16009 private:
16011 const bool is_little_endian = little_endianness();
16012
16014 output_adapter_t<CharType> oa = nullptr;
16015 };
16016 } // namespace detail
16017} // namespace nlohmann
16018
16019// #include <nlohmann/detail/output/output_adapters.hpp>
16020
16021// #include <nlohmann/detail/output/serializer.hpp>
16022
16023
16024#include <algorithm> // reverse, remove, fill, find, none_of
16025#include <array> // array
16026#include <clocale> // localeconv, lconv
16027#include <cmath> // labs, isfinite, isnan, signbit
16028#include <cstddef> // size_t, ptrdiff_t
16029#include <cstdint> // uint8_t
16030#include <cstdio> // snprintf
16031#include <limits> // numeric_limits
16032#include <string> // string, char_traits
16033#include <iomanip> // setfill, setw
16034#include <type_traits> // is_same
16035#include <utility> // move
16036
16037// #include <nlohmann/detail/conversions/to_chars.hpp>
16038
16039
16040#include <array> // array
16041#include <cmath> // signbit, isfinite
16042#include <cstdint> // intN_t, uintN_t
16043#include <cstring> // memcpy, memmove
16044#include <limits> // numeric_limits
16045#include <type_traits> // conditional
16046
16047// #include <nlohmann/detail/macro_scope.hpp>
16048
16049
16050namespace nlohmann
16051{
16052 namespace detail
16053 {
16054
16074 namespace dtoa_impl
16075 {
16076
16077 template<typename Target, typename Source>
16078 Target reinterpret_bits(const Source source)
16079 {
16080 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16081
16082 Target target;
16083 std::memcpy(&target, &source, sizeof(Source));
16084 return target;
16085 }
16086
16087 struct diyfp // f * 2^e
16088 {
16089 static constexpr int kPrecision = 64; // = q
16090
16091 std::uint64_t f = 0;
16092 int e = 0;
16093
16094 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16095
16100 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16101 {
16102 JSON_ASSERT(x.e == y.e);
16103 JSON_ASSERT(x.f >= y.f);
16104
16105 return { x.f - y.f, x.e };
16106 }
16107
16112 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16113 {
16114 static_assert(kPrecision == 64, "internal error");
16115
16116 // Computes:
16117 // f = round((x.f * y.f) / 2^q)
16118 // e = x.e + y.e + q
16119
16120 // Emulate the 64-bit * 64-bit multiplication:
16121 //
16122 // p = u * v
16123 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
16124 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
16125 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
16126 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
16127 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
16128 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
16129 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
16130 //
16131 // (Since Q might be larger than 2^32 - 1)
16132 //
16133 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
16134 //
16135 // (Q_hi + H does not overflow a 64-bit int)
16136 //
16137 // = p_lo + 2^64 p_hi
16138
16139 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
16140 const std::uint64_t u_hi = x.f >> 32u;
16141 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
16142 const std::uint64_t v_hi = y.f >> 32u;
16143
16144 const std::uint64_t p0 = u_lo * v_lo;
16145 const std::uint64_t p1 = u_lo * v_hi;
16146 const std::uint64_t p2 = u_hi * v_lo;
16147 const std::uint64_t p3 = u_hi * v_hi;
16148
16149 const std::uint64_t p0_hi = p0 >> 32u;
16150 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
16151 const std::uint64_t p1_hi = p1 >> 32u;
16152 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
16153 const std::uint64_t p2_hi = p2 >> 32u;
16154
16155 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
16156
16157 // The full product might now be computed as
16158 //
16159 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16160 // p_lo = p0_lo + (Q << 32)
16161 //
16162 // But in this particular case here, the full p_lo is not required.
16163 // Effectively we only need to add the highest bit in p_lo to p_hi (and
16164 // Q_hi + 1 does not overflow).
16165
16166 Q += std::uint64_t{ 1 } << (64u - 32u - 1u); // round, ties up
16167
16168 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16169
16170 return { h, x.e + y.e + 64 };
16171 }
16172
16177 static diyfp normalize(diyfp x) noexcept
16178 {
16179 JSON_ASSERT(x.f != 0);
16180
16181 while ((x.f >> 63u) == 0)
16182 {
16183 x.f <<= 1u;
16184 x.e--;
16185 }
16186
16187 return x;
16188 }
16189
16194 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16195 {
16196 const int delta = x.e - target_exponent;
16197
16198 JSON_ASSERT(delta >= 0);
16199 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16200
16201 return { x.f << delta, target_exponent };
16202 }
16203 };
16204
16206 {
16210 };
16211
16218 template<typename FloatType>
16220 {
16221 JSON_ASSERT(std::isfinite(value));
16222 JSON_ASSERT(value > 0);
16223
16224 // Convert the IEEE representation into a diyfp.
16225 //
16226 // If v is denormal:
16227 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
16228 // If v is normalized:
16229 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
16230
16231 static_assert(std::numeric_limits<FloatType>::is_iec559,
16232 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
16233
16234 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
16235 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
16236 constexpr int kMinExp = 1 - kBias;
16237 constexpr std::uint64_t kHiddenBit = std::uint64_t{ 1 } << (kPrecision - 1); // = 2^(p-1)
16238
16239 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
16240
16241 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
16242 const std::uint64_t E = bits >> (kPrecision - 1);
16243 const std::uint64_t F = bits & (kHiddenBit - 1);
16244
16245 const bool is_denormal = E == 0;
16246 const diyfp v = is_denormal
16247 ? diyfp(F, kMinExp)
16248 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
16249
16250 // Compute the boundaries m- and m+ of the floating-point value
16251 // v = f * 2^e.
16252 //
16253 // Determine v- and v+, the floating-point predecessor and successor if v,
16254 // respectively.
16255 //
16256 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
16257 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
16258 //
16259 // v+ = v + 2^e
16260 //
16261 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
16262 // between m- and m+ round to v, regardless of how the input rounding
16263 // algorithm breaks ties.
16264 //
16265 // ---+-------------+-------------+-------------+-------------+--- (A)
16266 // v- m- v m+ v+
16267 //
16268 // -----------------+------+------+-------------+-------------+--- (B)
16269 // v- m- v m+ v+
16270
16271 const bool lower_boundary_is_closer = F == 0 && E > 1;
16272 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
16273 const diyfp m_minus = lower_boundary_is_closer
16274 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
16275 : diyfp(2 * v.f - 1, v.e - 1); // (A)
16276
16277// Determine the normalized w+ = m+.
16278 const diyfp w_plus = diyfp::normalize(m_plus);
16279
16280 // Determine w- = m- such that e_(w-) = e_(w+).
16281 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
16282
16283 return { diyfp::normalize(v), w_minus, w_plus };
16284 }
16285
16286 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
16287 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
16288 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
16289 //
16290 // alpha <= e = e_c + e_w + q <= gamma
16291 //
16292 // or
16293 //
16294 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
16295 // <= f_c * f_w * 2^gamma
16296 //
16297 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
16298 //
16299 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
16300 //
16301 // or
16302 //
16303 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
16304 //
16305 // The choice of (alpha,gamma) determines the size of the table and the form of
16306 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
16307 // in practice:
16308 //
16309 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
16310 // processed independently: An integral part p1, and a fractional part p2:
16311 //
16312 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
16313 // = (f div 2^-e) + (f mod 2^-e) * 2^e
16314 // = p1 + p2 * 2^e
16315 //
16316 // The conversion of p1 into decimal form requires a series of divisions and
16317 // modulos by (a power of) 10. These operations are faster for 32-bit than for
16318 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
16319 // achieved by choosing
16320 //
16321 // -e >= 32 or e <= -32 := gamma
16322 //
16323 // In order to convert the fractional part
16324 //
16325 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
16326 //
16327 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
16328 // d[-i] are extracted in order:
16329 //
16330 // (10 * p2) div 2^-e = d[-1]
16331 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
16332 //
16333 // The multiplication by 10 must not overflow. It is sufficient to choose
16334 //
16335 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
16336 //
16337 // Since p2 = f mod 2^-e < 2^-e,
16338 //
16339 // -e <= 60 or e >= -60 := alpha
16340
16341 constexpr int kAlpha = -60;
16342 constexpr int kGamma = -32;
16343
16344 struct cached_power // c = f * 2^e ~= 10^k
16345 {
16346 std::uint64_t f;
16347 int e;
16348 int k;
16349 };
16350
16359 {
16360 // Now
16361 //
16362 // alpha <= e_c + e + q <= gamma (1)
16363 // ==> f_c * 2^alpha <= c * 2^e * 2^q
16364 //
16365 // and since the c's are normalized, 2^(q-1) <= f_c,
16366 //
16367 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
16368 // ==> 2^(alpha - e - 1) <= c
16369 //
16370 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
16371 //
16372 // k = ceil( log_10( 2^(alpha - e - 1) ) )
16373 // = ceil( (alpha - e - 1) * log_10(2) )
16374 //
16375 // From the paper:
16376 // "In theory the result of the procedure could be wrong since c is rounded,
16377 // and the computation itself is approximated [...]. In practice, however,
16378 // this simple function is sufficient."
16379 //
16380 // For IEEE double precision floating-point numbers converted into
16381 // normalized diyfp's w = f * 2^e, with q = 64,
16382 //
16383 // e >= -1022 (min IEEE exponent)
16384 // -52 (p - 1)
16385 // -52 (p - 1, possibly normalize denormal IEEE numbers)
16386 // -11 (normalize the diyfp)
16387 // = -1137
16388 //
16389 // and
16390 //
16391 // e <= +1023 (max IEEE exponent)
16392 // -52 (p - 1)
16393 // -11 (normalize the diyfp)
16394 // = 960
16395 //
16396 // This binary exponent range [-1137,960] results in a decimal exponent
16397 // range [-307,324]. One does not need to store a cached power for each
16398 // k in this range. For each such k it suffices to find a cached power
16399 // such that the exponent of the product lies in [alpha,gamma].
16400 // This implies that the difference of the decimal exponents of adjacent
16401 // table entries must be less than or equal to
16402 //
16403 // floor( (gamma - alpha) * log_10(2) ) = 8.
16404 //
16405 // (A smaller distance gamma-alpha would require a larger table.)
16406
16407 // NB:
16408 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
16409
16410 constexpr int kCachedPowersMinDecExp = -300;
16411 constexpr int kCachedPowersDecStep = 8;
16412
16413 static constexpr std::array<cached_power, 79> kCachedPowers =
16414 {
16415 {
16416 { 0xAB70FE17C79AC6CA, -1060, -300 },
16417 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
16418 { 0xBE5691EF416BD60C, -1007, -284 },
16419 { 0x8DD01FAD907FFC3C, -980, -276 },
16420 { 0xD3515C2831559A83, -954, -268 },
16421 { 0x9D71AC8FADA6C9B5, -927, -260 },
16422 { 0xEA9C227723EE8BCB, -901, -252 },
16423 { 0xAECC49914078536D, -874, -244 },
16424 { 0x823C12795DB6CE57, -847, -236 },
16425 { 0xC21094364DFB5637, -821, -228 },
16426 { 0x9096EA6F3848984F, -794, -220 },
16427 { 0xD77485CB25823AC7, -768, -212 },
16428 { 0xA086CFCD97BF97F4, -741, -204 },
16429 { 0xEF340A98172AACE5, -715, -196 },
16430 { 0xB23867FB2A35B28E, -688, -188 },
16431 { 0x84C8D4DFD2C63F3B, -661, -180 },
16432 { 0xC5DD44271AD3CDBA, -635, -172 },
16433 { 0x936B9FCEBB25C996, -608, -164 },
16434 { 0xDBAC6C247D62A584, -582, -156 },
16435 { 0xA3AB66580D5FDAF6, -555, -148 },
16436 { 0xF3E2F893DEC3F126, -529, -140 },
16437 { 0xB5B5ADA8AAFF80B8, -502, -132 },
16438 { 0x87625F056C7C4A8B, -475, -124 },
16439 { 0xC9BCFF6034C13053, -449, -116 },
16440 { 0x964E858C91BA2655, -422, -108 },
16441 { 0xDFF9772470297EBD, -396, -100 },
16442 { 0xA6DFBD9FB8E5B88F, -369, -92 },
16443 { 0xF8A95FCF88747D94, -343, -84 },
16444 { 0xB94470938FA89BCF, -316, -76 },
16445 { 0x8A08F0F8BF0F156B, -289, -68 },
16446 { 0xCDB02555653131B6, -263, -60 },
16447 { 0x993FE2C6D07B7FAC, -236, -52 },
16448 { 0xE45C10C42A2B3B06, -210, -44 },
16449 { 0xAA242499697392D3, -183, -36 },
16450 { 0xFD87B5F28300CA0E, -157, -28 },
16451 { 0xBCE5086492111AEB, -130, -20 },
16452 { 0x8CBCCC096F5088CC, -103, -12 },
16453 { 0xD1B71758E219652C, -77, -4 },
16454 { 0x9C40000000000000, -50, 4 },
16455 { 0xE8D4A51000000000, -24, 12 },
16456 { 0xAD78EBC5AC620000, 3, 20 },
16457 { 0x813F3978F8940984, 30, 28 },
16458 { 0xC097CE7BC90715B3, 56, 36 },
16459 { 0x8F7E32CE7BEA5C70, 83, 44 },
16460 { 0xD5D238A4ABE98068, 109, 52 },
16461 { 0x9F4F2726179A2245, 136, 60 },
16462 { 0xED63A231D4C4FB27, 162, 68 },
16463 { 0xB0DE65388CC8ADA8, 189, 76 },
16464 { 0x83C7088E1AAB65DB, 216, 84 },
16465 { 0xC45D1DF942711D9A, 242, 92 },
16466 { 0x924D692CA61BE758, 269, 100 },
16467 { 0xDA01EE641A708DEA, 295, 108 },
16468 { 0xA26DA3999AEF774A, 322, 116 },
16469 { 0xF209787BB47D6B85, 348, 124 },
16470 { 0xB454E4A179DD1877, 375, 132 },
16471 { 0x865B86925B9BC5C2, 402, 140 },
16472 { 0xC83553C5C8965D3D, 428, 148 },
16473 { 0x952AB45CFA97A0B3, 455, 156 },
16474 { 0xDE469FBD99A05FE3, 481, 164 },
16475 { 0xA59BC234DB398C25, 508, 172 },
16476 { 0xF6C69A72A3989F5C, 534, 180 },
16477 { 0xB7DCBF5354E9BECE, 561, 188 },
16478 { 0x88FCF317F22241E2, 588, 196 },
16479 { 0xCC20CE9BD35C78A5, 614, 204 },
16480 { 0x98165AF37B2153DF, 641, 212 },
16481 { 0xE2A0B5DC971F303A, 667, 220 },
16482 { 0xA8D9D1535CE3B396, 694, 228 },
16483 { 0xFB9B7CD9A4A7443C, 720, 236 },
16484 { 0xBB764C4CA7A44410, 747, 244 },
16485 { 0x8BAB8EEFB6409C1A, 774, 252 },
16486 { 0xD01FEF10A657842C, 800, 260 },
16487 { 0x9B10A4E5E9913129, 827, 268 },
16488 { 0xE7109BFBA19C0C9D, 853, 276 },
16489 { 0xAC2820D9623BF429, 880, 284 },
16490 { 0x80444B5E7AA7CF85, 907, 292 },
16491 { 0xBF21E44003ACDD2D, 933, 300 },
16492 { 0x8E679C2F5E44FF8F, 960, 308 },
16493 { 0xD433179D9C8CB841, 986, 316 },
16494 { 0x9E19DB92B4E31BA9, 1013, 324 },
16495 }
16496 };
16497
16498 // This computation gives exactly the same results for k as
16499 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
16500 // for |e| <= 1500, but doesn't require floating-point operations.
16501 // NB: log_10(2) ~= 78913 / 2^18
16502 JSON_ASSERT(e >= -1500);
16503 JSON_ASSERT(e <= 1500);
16504 const int f = kAlpha - e - 1;
16505 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
16506
16507 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
16508 JSON_ASSERT(index >= 0);
16509 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
16510
16511 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
16512 JSON_ASSERT(kAlpha <= cached.e + e + 64);
16513 JSON_ASSERT(kGamma >= cached.e + e + 64);
16514
16515 return cached;
16516 }
16517
16522 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
16523 {
16524 // LCOV_EXCL_START
16525 if (n >= 1000000000)
16526 {
16527 pow10 = 1000000000;
16528 return 10;
16529 }
16530 // LCOV_EXCL_STOP
16531 if (n >= 100000000)
16532 {
16533 pow10 = 100000000;
16534 return 9;
16535 }
16536 if (n >= 10000000)
16537 {
16538 pow10 = 10000000;
16539 return 8;
16540 }
16541 if (n >= 1000000)
16542 {
16543 pow10 = 1000000;
16544 return 7;
16545 }
16546 if (n >= 100000)
16547 {
16548 pow10 = 100000;
16549 return 6;
16550 }
16551 if (n >= 10000)
16552 {
16553 pow10 = 10000;
16554 return 5;
16555 }
16556 if (n >= 1000)
16557 {
16558 pow10 = 1000;
16559 return 4;
16560 }
16561 if (n >= 100)
16562 {
16563 pow10 = 100;
16564 return 3;
16565 }
16566 if (n >= 10)
16567 {
16568 pow10 = 10;
16569 return 2;
16570 }
16571
16572 pow10 = 1;
16573 return 1;
16574 }
16575
16576 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
16577 std::uint64_t rest, std::uint64_t ten_k)
16578 {
16579 JSON_ASSERT(len >= 1);
16580 JSON_ASSERT(dist <= delta);
16581 JSON_ASSERT(rest <= delta);
16582 JSON_ASSERT(ten_k > 0);
16583
16584 // <--------------------------- delta ---->
16585 // <---- dist --------->
16586 // --------------[------------------+-------------------]--------------
16587 // M- w M+
16588 //
16589 // ten_k
16590 // <------>
16591 // <---- rest ---->
16592 // --------------[------------------+----+--------------]--------------
16593 // w V
16594 // = buf * 10^k
16595 //
16596 // ten_k represents a unit-in-the-last-place in the decimal representation
16597 // stored in buf.
16598 // Decrement buf by ten_k while this takes buf closer to w.
16599
16600 // The tests are written in this order to avoid overflow in unsigned
16601 // integer arithmetic.
16602
16603 while (rest < dist
16604 && delta - rest >= ten_k
16605 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
16606 {
16607 JSON_ASSERT(buf[len - 1] != '0');
16608 buf[len - 1]--;
16609 rest += ten_k;
16610 }
16611 }
16612
16617 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
16618 diyfp M_minus, diyfp w, diyfp M_plus)
16619 {
16620 static_assert(kAlpha >= -60, "internal error");
16621 static_assert(kGamma <= -32, "internal error");
16622
16623 // Generates the digits (and the exponent) of a decimal floating-point
16624 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
16625 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
16626 //
16627 // <--------------------------- delta ---->
16628 // <---- dist --------->
16629 // --------------[------------------+-------------------]--------------
16630 // M- w M+
16631 //
16632 // Grisu2 generates the digits of M+ from left to right and stops as soon as
16633 // V is in [M-,M+].
16634
16635 JSON_ASSERT(M_plus.e >= kAlpha);
16636 JSON_ASSERT(M_plus.e <= kGamma);
16637
16638 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
16639 std::uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
16640
16641 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
16642 //
16643 // M+ = f * 2^e
16644 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
16645 // = ((p1 ) * 2^-e + (p2 )) * 2^e
16646 // = p1 + p2 * 2^e
16647
16648 const diyfp one(std::uint64_t{ 1 } << -M_plus.e, M_plus.e);
16649
16650 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
16651 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
16652
16653 // 1)
16654 //
16655 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
16656
16657 JSON_ASSERT(p1 > 0);
16658
16659 std::uint32_t pow10{};
16660 const int k = find_largest_pow10(p1, pow10);
16661
16662 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
16663 //
16664 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
16665 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
16666 //
16667 // M+ = p1 + p2 * 2^e
16668 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
16669 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
16670 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
16671 //
16672 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
16673 //
16674 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
16675 //
16676 // but stop as soon as
16677 //
16678 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
16679
16680 int n = k;
16681 while (n > 0)
16682 {
16683 // Invariants:
16684 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
16685 // pow10 = 10^(n-1) <= p1 < 10^n
16686 //
16687 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
16688 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
16689 //
16690 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
16691 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
16692 //
16693 JSON_ASSERT(d <= 9);
16694 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16695 //
16696 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
16697 //
16698 p1 = r;
16699 n--;
16700 //
16701 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
16702 // pow10 = 10^n
16703 //
16704
16705 // Now check if enough digits have been generated.
16706 // Compute
16707 //
16708 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
16709 //
16710 // Note:
16711 // Since rest and delta share the same exponent e, it suffices to
16712 // compare the significands.
16713 const std::uint64_t rest = (std::uint64_t{ p1 } << -one.e) + p2;
16714 if (rest <= delta)
16715 {
16716 // V = buffer * 10^n, with M- <= V <= M+.
16717
16718 decimal_exponent += n;
16719
16720 // We may now just stop. But instead look if the buffer could be
16721 // decremented to bring V closer to w.
16722 //
16723 // pow10 = 10^n is now 1 ulp in the decimal representation V.
16724 // The rounding procedure works with diyfp's with an implicit
16725 // exponent of e.
16726 //
16727 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16728 //
16729 const std::uint64_t ten_n = std::uint64_t{ pow10 } << -one.e;
16730 grisu2_round(buffer, length, dist, delta, rest, ten_n);
16731
16732 return;
16733 }
16734
16735 pow10 /= 10;
16736 //
16737 // pow10 = 10^(n-1) <= p1 < 10^n
16738 // Invariants restored.
16739 }
16740
16741 // 2)
16742 //
16743 // The digits of the integral part have been generated:
16744 //
16745 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16746 // = buffer + p2 * 2^e
16747 //
16748 // Now generate the digits of the fractional part p2 * 2^e.
16749 //
16750 // Note:
16751 // No decimal point is generated: the exponent is adjusted instead.
16752 //
16753 // p2 actually represents the fraction
16754 //
16755 // p2 * 2^e
16756 // = p2 / 2^-e
16757 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16758 //
16759 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16760 //
16761 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16762 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16763 //
16764 // using
16765 //
16766 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16767 // = ( d) * 2^-e + ( r)
16768 //
16769 // or
16770 // 10^m * p2 * 2^e = d + r * 2^e
16771 //
16772 // i.e.
16773 //
16774 // M+ = buffer + p2 * 2^e
16775 // = buffer + 10^-m * (d + r * 2^e)
16776 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16777 //
16778 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16779
16780 JSON_ASSERT(p2 > delta);
16781
16782 int m = 0;
16783 for (;;)
16784 {
16785 // Invariant:
16786 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16787 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16788 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16789 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16790 //
16791 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16792 p2 *= 10;
16793 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16794 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16795 //
16796 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16797 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16798 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16799 //
16800 JSON_ASSERT(d <= 9);
16801 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16802 //
16803 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16804 //
16805 p2 = r;
16806 m++;
16807 //
16808 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16809 // Invariant restored.
16810
16811 // Check if enough digits have been generated.
16812 //
16813 // 10^-m * p2 * 2^e <= delta * 2^e
16814 // p2 * 2^e <= 10^m * delta * 2^e
16815 // p2 <= 10^m * delta
16816 delta *= 10;
16817 dist *= 10;
16818 if (p2 <= delta)
16819 {
16820 break;
16821 }
16822 }
16823
16824 // V = buffer * 10^-m, with M- <= V <= M+.
16825
16826 decimal_exponent -= m;
16827
16828 // 1 ulp in the decimal representation is now 10^-m.
16829 // Since delta and dist are now scaled by 10^m, we need to do the
16830 // same with ulp in order to keep the units in sync.
16831 //
16832 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16833 //
16834 const std::uint64_t ten_m = one.f;
16835 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16836
16837 // By construction this algorithm generates the shortest possible decimal
16838 // number (Loitsch, Theorem 6.2) which rounds back to w.
16839 // For an input number of precision p, at least
16840 //
16841 // N = 1 + ceil(p * log_10(2))
16842 //
16843 // decimal digits are sufficient to identify all binary floating-point
16844 // numbers (Matula, "In-and-Out conversions").
16845 // This implies that the algorithm does not produce more than N decimal
16846 // digits.
16847 //
16848 // N = 17 for p = 53 (IEEE double precision)
16849 // N = 9 for p = 24 (IEEE single precision)
16850 }
16851
16858 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16859 diyfp m_minus, diyfp v, diyfp m_plus)
16860 {
16861 JSON_ASSERT(m_plus.e == m_minus.e);
16862 JSON_ASSERT(m_plus.e == v.e);
16863
16864 // --------(-----------------------+-----------------------)-------- (A)
16865 // m- v m+
16866 //
16867 // --------------------(-----------+-----------------------)-------- (B)
16868 // m- v m+
16869 //
16870 // First scale v (and m- and m+) such that the exponent is in the range
16871 // [alpha, gamma].
16872
16873 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16874
16875 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16876
16877 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16878 const diyfp w = diyfp::mul(v, c_minus_k);
16879 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16880 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16881
16882 // ----(---+---)---------------(---+---)---------------(---+---)----
16883 // w- w w+
16884 // = c*m- = c*v = c*m+
16885 //
16886 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16887 // w+ are now off by a small amount.
16888 // In fact:
16889 //
16890 // w - v * 10^k < 1 ulp
16891 //
16892 // To account for this inaccuracy, add resp. subtract 1 ulp.
16893 //
16894 // --------+---[---------------(---+---)---------------]---+--------
16895 // w- M- w M+ w+
16896 //
16897 // Now any number in [M-, M+] (bounds included) will round to w when input,
16898 // regardless of how the input rounding algorithm breaks ties.
16899 //
16900 // And digit_gen generates the shortest possible such number in [M-, M+].
16901 // Note that this does not mean that Grisu2 always generates the shortest
16902 // possible number in the interval (m-, m+).
16903 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16904 const diyfp M_plus(w_plus.f - 1, w_plus.e);
16905
16906 decimal_exponent = -cached.k; // = -(-k) = k
16907
16908 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16909 }
16910
16916 template<typename FloatType>
16918 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16919 {
16920 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16921 "internal error: not enough precision");
16922
16923 JSON_ASSERT(std::isfinite(value));
16924 JSON_ASSERT(value > 0);
16925
16926 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16927 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16928 // decimal representations are not exactly "short".
16929 //
16930 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16931 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16932 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
16933 // does.
16934 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16935 // representation using the corresponding std::from_chars function recovers value exactly". That
16936 // indicates that single precision floating-point numbers should be recovered using
16937 // 'std::strtof'.
16938 //
16939 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16940 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16941 // value is off by 1 ulp.
16942#if 0
16943 const boundaries w = compute_boundaries(static_cast<double>(value));
16944#else
16946#endif
16947
16948 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16949 }
16950
16958 inline char* append_exponent(char* buf, int e)
16959 {
16960 JSON_ASSERT(e > -1000);
16961 JSON_ASSERT(e < 1000);
16962
16963 if (e < 0)
16964 {
16965 e = -e;
16966 *buf++ = '-';
16967 }
16968 else
16969 {
16970 *buf++ = '+';
16971 }
16972
16973 auto k = static_cast<std::uint32_t>(e);
16974 if (k < 10)
16975 {
16976 // Always print at least two digits in the exponent.
16977 // This is for compatibility with printf("%g").
16978 *buf++ = '0';
16979 *buf++ = static_cast<char>('0' + k);
16980 }
16981 else if (k < 100)
16982 {
16983 *buf++ = static_cast<char>('0' + k / 10);
16984 k %= 10;
16985 *buf++ = static_cast<char>('0' + k);
16986 }
16987 else
16988 {
16989 *buf++ = static_cast<char>('0' + k / 100);
16990 k %= 100;
16991 *buf++ = static_cast<char>('0' + k / 10);
16992 k %= 10;
16993 *buf++ = static_cast<char>('0' + k);
16994 }
16995
16996 return buf;
16997 }
16998
17010 inline char* format_buffer(char* buf, int len, int decimal_exponent,
17011 int min_exp, int max_exp)
17012 {
17013 JSON_ASSERT(min_exp < 0);
17014 JSON_ASSERT(max_exp > 0);
17015
17016 const int k = len;
17017 const int n = len + decimal_exponent;
17018
17019 // v = buf * 10^(n-k)
17020 // k is the length of the buffer (number of decimal digits)
17021 // n is the position of the decimal point relative to the start of the buffer.
17022
17023 if (k <= n && n <= max_exp)
17024 {
17025 // digits[000]
17026 // len <= max_exp + 2
17027
17028 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17029 // Make it look like a floating-point number (#362, #378)
17030 buf[n + 0] = '.';
17031 buf[n + 1] = '0';
17032 return buf + (static_cast<size_t>(n) + 2);
17033 }
17034
17035 if (0 < n && n <= max_exp)
17036 {
17037 // dig.its
17038 // len <= max_digits10 + 1
17039
17040 JSON_ASSERT(k > n);
17041
17042 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17043 buf[n] = '.';
17044 return buf + (static_cast<size_t>(k) + 1U);
17045 }
17046
17047 if (min_exp < n && n <= 0)
17048 {
17049 // 0.[000]digits
17050 // len <= 2 + (-min_exp - 1) + max_digits10
17051
17052 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17053 buf[0] = '0';
17054 buf[1] = '.';
17055 std::memset(buf + 2, '0', static_cast<size_t>(-n));
17056 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17057 }
17058
17059 if (k == 1)
17060 {
17061 // dE+123
17062 // len <= 1 + 5
17063
17064 buf += 1;
17065 }
17066 else
17067 {
17068 // d.igitsE+123
17069 // len <= max_digits10 + 1 + 5
17070
17071 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17072 buf[1] = '.';
17073 buf += 1 + static_cast<size_t>(k);
17074 }
17075
17076 *buf++ = 'e';
17077 return append_exponent(buf, n - 1);
17078 }
17079
17080 } // namespace dtoa_impl
17081
17092 template<typename FloatType>
17095 char* to_chars(char* first, const char* last, FloatType value)
17096 {
17097 static_cast<void>(last); // maybe unused - fix warning
17098 JSON_ASSERT(std::isfinite(value));
17099
17100 // Use signbit(value) instead of (value < 0) since signbit works for -0.
17101 if (std::signbit(value))
17102 {
17103 value = -value;
17104 *first++ = '-';
17105 }
17106
17107#ifdef __GNUC__
17108#pragma GCC diagnostic push
17109#pragma GCC diagnostic ignored "-Wfloat-equal"
17110#endif
17111 if (value == 0) // +-0
17112 {
17113 *first++ = '0';
17114 // Make it look like a floating-point number (#362, #378)
17115 *first++ = '.';
17116 *first++ = '0';
17117 return first;
17118 }
17119#ifdef __GNUC__
17120#pragma GCC diagnostic pop
17121#endif
17122
17123 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
17124
17125 // Compute v = buffer * 10^decimal_exponent.
17126 // The decimal digits are stored in the buffer, which needs to be interpreted
17127 // as an unsigned decimal integer.
17128 // len is the length of the buffer, i.e. the number of decimal digits.
17129 int len = 0;
17130 int decimal_exponent = 0;
17131 dtoa_impl::grisu2(first, len, decimal_exponent, value);
17132
17133 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
17134
17135 // Format the buffer like printf("%.*g", prec, value)
17136 constexpr int kMinExp = -4;
17137 // Use digits10 here to increase compatibility with version 2.
17138 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
17139
17140 JSON_ASSERT(last - first >= kMaxExp + 2);
17141 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
17142 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
17143
17144 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
17145 }
17146
17147 } // namespace detail
17148} // namespace nlohmann
17149
17150// #include <nlohmann/detail/exceptions.hpp>
17151
17152// #include <nlohmann/detail/macro_scope.hpp>
17153
17154// #include <nlohmann/detail/meta/cpp_future.hpp>
17155
17156// #include <nlohmann/detail/output/binary_writer.hpp>
17157
17158// #include <nlohmann/detail/output/output_adapters.hpp>
17159
17160// #include <nlohmann/detail/string_concat.hpp>
17161
17162// #include <nlohmann/detail/value_t.hpp>
17163
17164
17165namespace nlohmann
17166{
17167 namespace detail
17168 {
17170 // serialization //
17172
17175 {
17176 strict,
17177 replace,
17178 ignore
17179 };
17180
17181 template<typename BasicJsonType>
17183 {
17184 using string_t = typename BasicJsonType::string_t;
17185 using number_float_t = typename BasicJsonType::number_float_t;
17186 using number_integer_t = typename BasicJsonType::number_integer_t;
17187 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17188 using binary_char_t = typename BasicJsonType::binary_t::value_type;
17189 static constexpr std::uint8_t UTF8_ACCEPT = 0;
17190 static constexpr std::uint8_t UTF8_REJECT = 1;
17191
17192 public:
17200 : o(std::move(s))
17201 , loc(std::localeconv())
17202 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
17203 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->decimal_point)))
17204 , indent_char(ichar)
17206 , error_handler(error_handler_)
17207 {}
17208
17209 // delete because of pointer members
17210 serializer(const serializer&) = delete;
17214 ~serializer() = default;
17215
17238 void dump(const BasicJsonType& val,
17239 const bool pretty_print,
17240 const bool ensure_ascii,
17241 const unsigned int indent_step,
17242 const unsigned int current_indent = 0)
17243 {
17244 switch (val.m_type)
17245 {
17246 case value_t::object:
17247 {
17248 if (val.m_value.object->empty())
17249 {
17250 o->write_characters("{}", 2);
17251 return;
17252 }
17253
17254 if (pretty_print)
17255 {
17256 o->write_characters("{\n", 2);
17257
17258 // variable to hold indentation for recursive calls
17259 const auto new_indent = current_indent + indent_step;
17260 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17261 {
17262 indent_string.resize(indent_string.size() * 2, ' ');
17263 }
17264
17265 // first n-1 elements
17266 auto i = val.m_value.object->cbegin();
17267 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17268 {
17269 o->write_characters(indent_string.c_str(), new_indent);
17270 o->write_character('\"');
17271 dump_escaped(i->first, ensure_ascii);
17272 o->write_characters("\": ", 3);
17273 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17274 o->write_characters(",\n", 2);
17275 }
17276
17277 // last element
17278 JSON_ASSERT(i != val.m_value.object->cend());
17279 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17280 o->write_characters(indent_string.c_str(), new_indent);
17281 o->write_character('\"');
17282 dump_escaped(i->first, ensure_ascii);
17283 o->write_characters("\": ", 3);
17284 dump(i->second, true, ensure_ascii, indent_step, new_indent);
17285
17286 o->write_character('\n');
17287 o->write_characters(indent_string.c_str(), current_indent);
17288 o->write_character('}');
17289 }
17290 else
17291 {
17292 o->write_character('{');
17293
17294 // first n-1 elements
17295 auto i = val.m_value.object->cbegin();
17296 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17297 {
17298 o->write_character('\"');
17299 dump_escaped(i->first, ensure_ascii);
17300 o->write_characters("\":", 2);
17301 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17302 o->write_character(',');
17303 }
17304
17305 // last element
17306 JSON_ASSERT(i != val.m_value.object->cend());
17307 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17308 o->write_character('\"');
17309 dump_escaped(i->first, ensure_ascii);
17310 o->write_characters("\":", 2);
17311 dump(i->second, false, ensure_ascii, indent_step, current_indent);
17312
17313 o->write_character('}');
17314 }
17315
17316 return;
17317 }
17318
17319 case value_t::array:
17320 {
17321 if (val.m_value.array->empty())
17322 {
17323 o->write_characters("[]", 2);
17324 return;
17325 }
17326
17327 if (pretty_print)
17328 {
17329 o->write_characters("[\n", 2);
17330
17331 // variable to hold indentation for recursive calls
17332 const auto new_indent = current_indent + indent_step;
17333 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17334 {
17335 indent_string.resize(indent_string.size() * 2, ' ');
17336 }
17337
17338 // first n-1 elements
17339 for (auto i = val.m_value.array->cbegin();
17340 i != val.m_value.array->cend() - 1; ++i)
17341 {
17342 o->write_characters(indent_string.c_str(), new_indent);
17343 dump(*i, true, ensure_ascii, indent_step, new_indent);
17344 o->write_characters(",\n", 2);
17345 }
17346
17347 // last element
17348 JSON_ASSERT(!val.m_value.array->empty());
17349 o->write_characters(indent_string.c_str(), new_indent);
17350 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
17351
17352 o->write_character('\n');
17353 o->write_characters(indent_string.c_str(), current_indent);
17354 o->write_character(']');
17355 }
17356 else
17357 {
17358 o->write_character('[');
17359
17360 // first n-1 elements
17361 for (auto i = val.m_value.array->cbegin();
17362 i != val.m_value.array->cend() - 1; ++i)
17363 {
17364 dump(*i, false, ensure_ascii, indent_step, current_indent);
17365 o->write_character(',');
17366 }
17367
17368 // last element
17369 JSON_ASSERT(!val.m_value.array->empty());
17370 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
17371
17372 o->write_character(']');
17373 }
17374
17375 return;
17376 }
17377
17378 case value_t::string:
17379 {
17380 o->write_character('\"');
17381 dump_escaped(*val.m_value.string, ensure_ascii);
17382 o->write_character('\"');
17383 return;
17384 }
17385
17386 case value_t::binary:
17387 {
17388 if (pretty_print)
17389 {
17390 o->write_characters("{\n", 2);
17391
17392 // variable to hold indentation for recursive calls
17393 const auto new_indent = current_indent + indent_step;
17394 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17395 {
17396 indent_string.resize(indent_string.size() * 2, ' ');
17397 }
17398
17399 o->write_characters(indent_string.c_str(), new_indent);
17400
17401 o->write_characters("\"bytes\": [", 10);
17402
17403 if (!val.m_value.binary->empty())
17404 {
17405 for (auto i = val.m_value.binary->cbegin();
17406 i != val.m_value.binary->cend() - 1; ++i)
17407 {
17408 dump_integer(*i);
17409 o->write_characters(", ", 2);
17410 }
17411 dump_integer(val.m_value.binary->back());
17412 }
17413
17414 o->write_characters("],\n", 3);
17415 o->write_characters(indent_string.c_str(), new_indent);
17416
17417 o->write_characters("\"subtype\": ", 11);
17418 if (val.m_value.binary->has_subtype())
17419 {
17420 dump_integer(val.m_value.binary->subtype());
17421 }
17422 else
17423 {
17424 o->write_characters("null", 4);
17425 }
17426 o->write_character('\n');
17427 o->write_characters(indent_string.c_str(), current_indent);
17428 o->write_character('}');
17429 }
17430 else
17431 {
17432 o->write_characters("{\"bytes\":[", 10);
17433
17434 if (!val.m_value.binary->empty())
17435 {
17436 for (auto i = val.m_value.binary->cbegin();
17437 i != val.m_value.binary->cend() - 1; ++i)
17438 {
17439 dump_integer(*i);
17440 o->write_character(',');
17441 }
17442 dump_integer(val.m_value.binary->back());
17443 }
17444
17445 o->write_characters("],\"subtype\":", 12);
17446 if (val.m_value.binary->has_subtype())
17447 {
17448 dump_integer(val.m_value.binary->subtype());
17449 o->write_character('}');
17450 }
17451 else
17452 {
17453 o->write_characters("null}", 5);
17454 }
17455 }
17456 return;
17457 }
17458
17459 case value_t::boolean:
17460 {
17461 if (val.m_value.boolean)
17462 {
17463 o->write_characters("true", 4);
17464 }
17465 else
17466 {
17467 o->write_characters("false", 5);
17468 }
17469 return;
17470 }
17471
17473 {
17474 dump_integer(val.m_value.number_integer);
17475 return;
17476 }
17477
17479 {
17480 dump_integer(val.m_value.number_unsigned);
17481 return;
17482 }
17483
17485 {
17486 dump_float(val.m_value.number_float);
17487 return;
17488 }
17489
17490 case value_t::discarded:
17491 {
17492 o->write_characters("<discarded>", 11);
17493 return;
17494 }
17495
17496 case value_t::null:
17497 {
17498 o->write_characters("null", 4);
17499 return;
17500 }
17501
17502 default: // LCOV_EXCL_LINE
17503 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17504 }
17505 }
17506
17522 void dump_escaped(const string_t& s, const bool ensure_ascii)
17523 {
17524 std::uint32_t codepoint{};
17525 std::uint8_t state = UTF8_ACCEPT;
17526 std::size_t bytes = 0; // number of bytes written to string_buffer
17527
17528 // number of bytes written at the point of the last valid byte
17530 std::size_t undumped_chars = 0;
17531
17532 for (std::size_t i = 0; i < s.size(); ++i)
17533 {
17534 const auto byte = static_cast<std::uint8_t>(s[i]);
17535
17536 switch (decode(state, codepoint, byte))
17537 {
17538 case UTF8_ACCEPT: // decode found a new code point
17539 {
17540 switch (codepoint)
17541 {
17542 case 0x08: // backspace
17543 {
17544 string_buffer[bytes++] = '\\';
17545 string_buffer[bytes++] = 'b';
17546 break;
17547 }
17548
17549 case 0x09: // horizontal tab
17550 {
17551 string_buffer[bytes++] = '\\';
17552 string_buffer[bytes++] = 't';
17553 break;
17554 }
17555
17556 case 0x0A: // newline
17557 {
17558 string_buffer[bytes++] = '\\';
17559 string_buffer[bytes++] = 'n';
17560 break;
17561 }
17562
17563 case 0x0C: // formfeed
17564 {
17565 string_buffer[bytes++] = '\\';
17566 string_buffer[bytes++] = 'f';
17567 break;
17568 }
17569
17570 case 0x0D: // carriage return
17571 {
17572 string_buffer[bytes++] = '\\';
17573 string_buffer[bytes++] = 'r';
17574 break;
17575 }
17576
17577 case 0x22: // quotation mark
17578 {
17579 string_buffer[bytes++] = '\\';
17580 string_buffer[bytes++] = '\"';
17581 break;
17582 }
17583
17584 case 0x5C: // reverse solidus
17585 {
17586 string_buffer[bytes++] = '\\';
17587 string_buffer[bytes++] = '\\';
17588 break;
17589 }
17590
17591 default:
17592 {
17593 // escape control characters (0x00..0x1F) or, if
17594 // ensure_ascii parameter is used, non-ASCII characters
17595 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
17596 {
17597 if (codepoint <= 0xFFFF)
17598 {
17599 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17600 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
17601 static_cast<std::uint16_t>(codepoint)));
17602 bytes += 6;
17603 }
17604 else
17605 {
17606 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17607 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
17608 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
17609 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
17610 bytes += 12;
17611 }
17612 }
17613 else
17614 {
17615 // copy byte to buffer (all previous bytes
17616 // been copied have in default case above)
17617 string_buffer[bytes++] = s[i];
17618 }
17619 break;
17620 }
17621 }
17622
17623 // write buffer and reset index; there must be 13 bytes
17624 // left, as this is the maximal number of bytes to be
17625 // written ("\uxxxx\uxxxx\0") for one code point
17626 if (string_buffer.size() - bytes < 13)
17627 {
17628 o->write_characters(string_buffer.data(), bytes);
17629 bytes = 0;
17630 }
17631
17632 // remember the byte position of this accept
17634 undumped_chars = 0;
17635 break;
17636 }
17637
17638 case UTF8_REJECT: // decode found invalid UTF-8 byte
17639 {
17640 switch (error_handler)
17641 {
17643 {
17644 JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
17645 }
17646
17649 {
17650 // in case we saw this character the first time, we
17651 // would like to read it again, because the byte
17652 // may be OK for itself, but just not OK for the
17653 // previous sequence
17654 if (undumped_chars > 0)
17655 {
17656 --i;
17657 }
17658
17659 // reset length buffer to the last accepted index;
17660 // thus removing/ignoring the invalid characters
17662
17664 {
17665 // add a replacement character
17666 if (ensure_ascii)
17667 {
17668 string_buffer[bytes++] = '\\';
17669 string_buffer[bytes++] = 'u';
17670 string_buffer[bytes++] = 'f';
17671 string_buffer[bytes++] = 'f';
17672 string_buffer[bytes++] = 'f';
17673 string_buffer[bytes++] = 'd';
17674 }
17675 else
17676 {
17680 }
17681
17682 // write buffer and reset index; there must be 13 bytes
17683 // left, as this is the maximal number of bytes to be
17684 // written ("\uxxxx\uxxxx\0") for one code point
17685 if (string_buffer.size() - bytes < 13)
17686 {
17687 o->write_characters(string_buffer.data(), bytes);
17688 bytes = 0;
17689 }
17690
17692 }
17693
17694 undumped_chars = 0;
17695
17696 // continue processing the string
17697 state = UTF8_ACCEPT;
17698 break;
17699 }
17700
17701 default: // LCOV_EXCL_LINE
17702 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17703 }
17704 break;
17705 }
17706
17707 default: // decode found yet incomplete multi-byte code point
17708 {
17709 if (!ensure_ascii)
17710 {
17711 // code point will not be escaped - copy byte to buffer
17712 string_buffer[bytes++] = s[i];
17713 }
17715 break;
17716 }
17717 }
17718 }
17719
17720 // we finished processing the string
17721 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17722 {
17723 // write buffer
17724 if (bytes > 0)
17725 {
17726 o->write_characters(string_buffer.data(), bytes);
17727 }
17728 }
17729 else
17730 {
17731 // we finish reading, but do not accept: string was incomplete
17732 switch (error_handler)
17733 {
17735 {
17736 JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
17737 }
17738
17740 {
17741 // write all accepted bytes
17742 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17743 break;
17744 }
17745
17747 {
17748 // write all accepted bytes
17749 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17750 // add a replacement character
17751 if (ensure_ascii)
17752 {
17753 o->write_characters("\\ufffd", 6);
17754 }
17755 else
17756 {
17757 o->write_characters("\xEF\xBF\xBD", 3);
17758 }
17759 break;
17760 }
17761
17762 default: // LCOV_EXCL_LINE
17763 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17764 }
17765 }
17766 }
17767
17768 private:
17777 inline unsigned int count_digits(number_unsigned_t x) noexcept
17778 {
17779 unsigned int n_digits = 1;
17780 for (;;)
17781 {
17782 if (x < 10)
17783 {
17784 return n_digits;
17785 }
17786 if (x < 100)
17787 {
17788 return n_digits + 1;
17789 }
17790 if (x < 1000)
17791 {
17792 return n_digits + 2;
17793 }
17794 if (x < 10000)
17795 {
17796 return n_digits + 3;
17797 }
17798 x = x / 10000u;
17799 n_digits += 4;
17800 }
17801 }
17802
17808 static std::string hex_bytes(std::uint8_t byte)
17809 {
17810 std::string result = "FF";
17811 constexpr const char* nibble_to_hex = "0123456789ABCDEF";
17812 result[0] = nibble_to_hex[byte / 16];
17813 result[1] = nibble_to_hex[byte % 16];
17814 return result;
17815 }
17816
17817 // templates to avoid warnings about useless casts
17818 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
17819 bool is_negative_number(NumberType x)
17820 {
17821 return x < 0;
17822 }
17823
17824 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
17825 bool is_negative_number(NumberType /*unused*/)
17826 {
17827 return false;
17828 }
17829
17839 template < typename NumberType, detail::enable_if_t <
17840 std::is_integral<NumberType>::value ||
17841 std::is_same<NumberType, number_unsigned_t>::value ||
17842 std::is_same<NumberType, number_integer_t>::value ||
17843 std::is_same<NumberType, binary_char_t>::value,
17844 int > = 0 >
17845 void dump_integer(NumberType x)
17846 {
17847 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17848 {
17849 {
17850 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17851 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17852 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17853 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17854 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17855 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17856 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17857 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17858 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17859 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17860 }
17861 };
17862
17863 // special case for "0"
17864 if (x == 0)
17865 {
17866 o->write_character('0');
17867 return;
17868 }
17869
17870 // use a pointer to fill the buffer
17871 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17872
17873 number_unsigned_t abs_value;
17874
17875 unsigned int n_chars{};
17876
17877 if (is_negative_number(x))
17878 {
17879 *buffer_ptr = '-';
17880 abs_value = remove_sign(static_cast<number_integer_t>(x));
17881
17882 // account one more byte for the minus sign
17883 n_chars = 1 + count_digits(abs_value);
17884 }
17885 else
17886 {
17887 abs_value = static_cast<number_unsigned_t>(x);
17888 n_chars = count_digits(abs_value);
17889 }
17890
17891 // spare 1 byte for '\0'
17892 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17893
17894 // jump to the end to generate the string from backward,
17895 // so we later avoid reversing the result
17896 buffer_ptr += n_chars;
17897
17898 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17899 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17900 while (abs_value >= 100)
17901 {
17902 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17903 abs_value /= 100;
17904 *(--buffer_ptr) = digits_to_99[digits_index][1];
17905 *(--buffer_ptr) = digits_to_99[digits_index][0];
17906 }
17907
17908 if (abs_value >= 10)
17909 {
17910 const auto digits_index = static_cast<unsigned>(abs_value);
17911 *(--buffer_ptr) = digits_to_99[digits_index][1];
17912 *(--buffer_ptr) = digits_to_99[digits_index][0];
17913 }
17914 else
17915 {
17916 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17917 }
17918
17919 o->write_characters(number_buffer.data(), n_chars);
17920 }
17921
17930 void dump_float(number_float_t x)
17931 {
17932 // NaN / inf
17933 if (!std::isfinite(x))
17934 {
17935 o->write_characters("null", 4);
17936 return;
17937 }
17938
17939 // If number_float_t is an IEEE-754 single or double precision number,
17940 // use the Grisu2 algorithm to produce short numbers which are
17941 // guaranteed to round-trip, using strtof and strtod, resp.
17942 //
17943 // NB: The test below works if <long double> == <double>.
17944 static constexpr bool is_ieee_single_or_double
17945 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17946 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17947
17948 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17949 }
17950
17951 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17952 {
17953 auto* begin = number_buffer.data();
17955
17956 o->write_characters(begin, static_cast<size_t>(end - begin));
17957 }
17958
17959 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17960 {
17961 // get number of digits for a float -> text -> float round-trip
17962 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17963
17964 // the actual conversion
17965 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17966 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17967
17968 // negative value indicates an error
17969 JSON_ASSERT(len > 0);
17970 // check if buffer was large enough
17971 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17972
17973 // erase thousands separator
17974 if (thousands_sep != '\0')
17975 {
17976 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
17977 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
17978 std::fill(end, number_buffer.end(), '\0');
17979 JSON_ASSERT((end - number_buffer.begin()) <= len);
17980 len = (end - number_buffer.begin());
17981 }
17982
17983 // convert decimal point to '.'
17984 if (decimal_point != '\0' && decimal_point != '.')
17985 {
17986 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
17987 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17988 if (dec_pos != number_buffer.end())
17989 {
17990 *dec_pos = '.';
17991 }
17992 }
17993
17994 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17995
17996 // determine if we need to append ".0"
17997 const bool value_is_int_like =
17998 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17999 [](char c)
18000 {
18001 return c == '.' || c == 'e';
18002 });
18003
18004 if (value_is_int_like)
18005 {
18006 o->write_characters(".0", 2);
18007 }
18008 }
18009
18031 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18032 {
18033 static const std::array<std::uint8_t, 400> utf8d =
18034 {
18035 {
18036 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
18037 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
18038 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
18039 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
18040 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
18041 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
18042 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
18043 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18044 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18045 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18046 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
18047 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
18048 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
18049 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
18050 }
18051 };
18052
18053 JSON_ASSERT(byte < utf8d.size());
18054 const std::uint8_t type = utf8d[byte];
18055
18056 codep = (state != UTF8_ACCEPT)
18057 ? (byte & 0x3fu) | (codep << 6u)
18058 : (0xFFu >> type) & (byte);
18059
18060 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18061 JSON_ASSERT(index < 400);
18062 state = utf8d[index];
18063 return state;
18064 }
18065
18066 /*
18067 * Overload to make the compiler happy while it is instantiating
18068 * dump_integer for number_unsigned_t.
18069 * Must never be called.
18070 */
18071 number_unsigned_t remove_sign(number_unsigned_t x)
18072 {
18073 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18074 return x; // LCOV_EXCL_LINE
18075 }
18076
18077 /*
18078 * Helper function for dump_integer
18079 *
18080 * This function takes a negative signed integer and returns its absolute
18081 * value as unsigned integer. The plus/minus shuffling is necessary as we can
18082 * not directly remove the sign of an arbitrary signed integer as the
18083 * absolute values of INT_MIN and INT_MAX are usually not the same. See
18084 * #1708 for details.
18085 */
18086 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18087 {
18088 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18089 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18090 }
18091
18092 private:
18094 output_adapter_t<char> o = nullptr;
18095
18097 std::array<char, 64> number_buffer{ {} };
18098
18100 const std::lconv* loc = nullptr;
18102 const char thousands_sep = '\0';
18104 const char decimal_point = '\0';
18105
18107 std::array<char, 512> string_buffer{ {} };
18108
18110 const char indent_char;
18113
18116 };
18117 } // namespace detail
18118} // namespace nlohmann
18119
18120// #include <nlohmann/detail/value_t.hpp>
18121
18122// #include <nlohmann/json_fwd.hpp>
18123
18124// #include <nlohmann/ordered_map.hpp>
18125
18126
18127#include <functional> // equal_to, less
18128#include <initializer_list> // initializer_list
18129#include <iterator> // input_iterator_tag, iterator_traits
18130#include <memory> // allocator
18131#include <stdexcept> // for out_of_range
18132#include <type_traits> // enable_if, is_convertible
18133#include <utility> // pair
18134#include <vector> // vector
18135
18136// #include <nlohmann/detail/macro_scope.hpp>
18137
18138
18139namespace nlohmann
18140{
18141
18144 template <class Key, class T, class IgnoredLess = std::less<Key>,
18145 class Allocator = std::allocator<std::pair<const Key, T>>>
18146 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
18147 {
18148 using key_type = Key;
18149 using mapped_type = T;
18150 using Container = std::vector<std::pair<const Key, T>, Allocator>;
18151 using iterator = typename Container::iterator;
18152 using const_iterator = typename Container::const_iterator;
18153 using size_type = typename Container::size_type;
18154 using value_type = typename Container::value_type;
18155#ifdef JSON_HAS_CPP_14
18156 using key_compare = std::equal_to<>;
18157#else
18158 using key_compare = std::equal_to<Key>;
18159#endif
18160
18161 // Explicit constructors instead of `using Container::Container`
18162 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18163 ordered_map() noexcept(noexcept(Container())) : Container{} {}
18164 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{ alloc } {}
18165 template <class It>
18166 ordered_map(It first, It last, const Allocator& alloc = Allocator())
18167 : Container{ first, last, alloc } {}
18168 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator())
18169 : Container{ init, alloc } {}
18170
18171 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18172 {
18173 for (auto it = this->begin(); it != this->end(); ++it)
18174 {
18175 if (m_compare(it->first, key))
18176 {
18177 return { it, false };
18178 }
18179 }
18180 Container::emplace_back(key, t);
18181 return { --this->end(), true };
18182 }
18183
18184 T& operator[](const Key& key)
18185 {
18186 return emplace(key, T{}).first->second;
18187 }
18188
18189 const T& operator[](const Key& key) const
18190 {
18191 return at(key);
18192 }
18193
18194 T& at(const Key& key)
18195 {
18196 for (auto it = this->begin(); it != this->end(); ++it)
18197 {
18198 if (m_compare(it->first, key))
18199 {
18200 return it->second;
18201 }
18202 }
18203
18204 JSON_THROW(std::out_of_range("key not found"));
18205 }
18206
18207 const T& at(const Key& key) const
18208 {
18209 for (auto it = this->begin(); it != this->end(); ++it)
18210 {
18211 if (m_compare(it->first, key))
18212 {
18213 return it->second;
18214 }
18215 }
18216
18217 JSON_THROW(std::out_of_range("key not found"));
18218 }
18219
18220 size_type erase(const Key& key)
18221 {
18222 for (auto it = this->begin(); it != this->end(); ++it)
18223 {
18224 if (m_compare(it->first, key))
18225 {
18226 // Since we cannot move const Keys, re-construct them in place
18227 for (auto next = it; ++next != this->end(); ++it)
18228 {
18229 it->~value_type(); // Destroy but keep allocation
18230 new (&*it) value_type{ std::move(*next) };
18231 }
18232 Container::pop_back();
18233 return 1;
18234 }
18235 }
18236 return 0;
18237 }
18238
18240 {
18241 return erase(pos, std::next(pos));
18242 }
18243
18245 {
18246 const auto elements_affected = std::distance(first, last);
18247 const auto offset = std::distance(Container::begin(), first);
18248
18249 // This is the start situation. We need to delete elements_affected
18250 // elements (3 in this example: e, f, g), and need to return an
18251 // iterator past the last deleted element (h in this example).
18252 // Note that offset is the distance from the start of the vector
18253 // to first. We will need this later.
18254
18255 // [ a, b, c, d, e, f, g, h, i, j ]
18256 // ^ ^
18257 // first last
18258
18259 // Since we cannot move const Keys, we re-construct them in place.
18260 // We start at first and re-construct (viz. copy) the elements from
18261 // the back of the vector. Example for first iteration:
18262
18263 // ,--------.
18264 // v | destroy e and re-construct with h
18265 // [ a, b, c, d, e, f, g, h, i, j ]
18266 // ^ ^
18267 // it it + elements_affected
18268
18269 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
18270 {
18271 it->~value_type(); // destroy but keep allocation
18272 new (&*it) value_type{ std::move(*std::next(it, elements_affected)) }; // "move" next element to it
18273 }
18274
18275 // [ a, b, c, d, h, i, j, h, i, j ]
18276 // ^ ^
18277 // first last
18278
18279 // remove the unneeded elements at the end of the vector
18280 Container::resize(this->size() - static_cast<size_type>(elements_affected));
18281
18282 // [ a, b, c, d, h, i, j ]
18283 // ^ ^
18284 // first last
18285
18286 // first is now pointing past the last deleted element, but we cannot
18287 // use this iterator, because it may have been invalidated by the
18288 // resize call. Instead, we can return begin() + offset.
18289 return Container::begin() + offset;
18290 }
18291
18292 size_type count(const Key& key) const
18293 {
18294 for (auto it = this->begin(); it != this->end(); ++it)
18295 {
18296 if (m_compare(it->first, key))
18297 {
18298 return 1;
18299 }
18300 }
18301 return 0;
18302 }
18303
18304 iterator find(const Key& key)
18305 {
18306 for (auto it = this->begin(); it != this->end(); ++it)
18307 {
18308 if (m_compare(it->first, key))
18309 {
18310 return it;
18311 }
18312 }
18313 return Container::end();
18314 }
18315
18316 const_iterator find(const Key& key) const
18317 {
18318 for (auto it = this->begin(); it != this->end(); ++it)
18319 {
18320 if (m_compare(it->first, key))
18321 {
18322 return it;
18323 }
18324 }
18325 return Container::end();
18326 }
18327
18328 std::pair<iterator, bool> insert(value_type&& value)
18329 {
18330 return emplace(value.first, std::move(value.second));
18331 }
18332
18333 std::pair<iterator, bool> insert(const value_type& value)
18334 {
18335 for (auto it = this->begin(); it != this->end(); ++it)
18336 {
18337 if (m_compare(it->first, value.first))
18338 {
18339 return { it, false };
18340 }
18341 }
18342 Container::push_back(value);
18343 return { --this->end(), true };
18344 }
18345
18346 template<typename InputIt>
18347 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
18348 std::input_iterator_tag>::value>::type;
18349
18350 template<typename InputIt, typename = require_input_iter<InputIt>>
18351 void insert(InputIt first, InputIt last)
18352 {
18353 for (auto it = first; it != last; ++it)
18354 {
18355 insert(*it);
18356 }
18357 }
18358
18359 private:
18361 };
18362
18363} // namespace nlohmann
18364
18365
18366#if defined(JSON_HAS_CPP_17)
18367#include <any>
18368#include <string_view>
18369#endif
18370
18376namespace nlohmann
18377{
18378
18398 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
18399 {
18400 private:
18401 template<detail::value_t> friend struct detail::external_constructor;
18402
18403 template<typename>
18404 friend class ::nlohmann::json_pointer;
18405 // can be restored when json_pointer backwards compatibility is removed
18406 // friend ::nlohmann::json_pointer<StringType>;
18407
18408 template<typename BasicJsonType, typename InputType>
18409 friend class ::nlohmann::detail::parser;
18410 friend ::nlohmann::detail::serializer<basic_json>;
18411 template<typename BasicJsonType>
18412 friend class ::nlohmann::detail::iter_impl;
18413 template<typename BasicJsonType, typename CharType>
18414 friend class ::nlohmann::detail::binary_writer;
18415 template<typename BasicJsonType, typename InputType, typename SAX>
18416 friend class ::nlohmann::detail::binary_reader;
18417 template<typename BasicJsonType>
18418 friend class ::nlohmann::detail::json_sax_dom_parser;
18419 template<typename BasicJsonType>
18420 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
18421 friend class ::nlohmann::detail::exception;
18422
18424 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
18425
18427 // convenience aliases for types residing in namespace detail;
18429
18430 template<typename InputAdapterType>
18431 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
18432 InputAdapterType adapter,
18434 const bool allow_exceptions = true,
18435 const bool ignore_comments = false
18436 )
18437 {
18438 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
18439 std::move(cb), allow_exceptions, ignore_comments);
18440 }
18441
18442 private:
18443 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
18444 template<typename BasicJsonType>
18446 template<typename BasicJsonType>
18448 template<typename Iterator>
18449 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
18450 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
18451
18452 template<typename CharType>
18454
18455 template<typename InputType>
18457 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
18458
18461
18462 public:
18466 template<typename T, typename SFINAE>
18467 using json_serializer = JSONSerializer<T, SFINAE>;
18473 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
18474
18478
18480 // exceptions //
18482
18486
18493
18495
18496
18498 // container types //
18500
18505
18508
18513
18515 using difference_type = std::ptrdiff_t;
18517 using size_type = std::size_t;
18518
18520 using allocator_type = AllocatorType<basic_json>;
18521
18523 using pointer = typename std::allocator_traits<allocator_type>::pointer;
18525 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
18526
18535
18537
18538
18542 {
18543 return allocator_type();
18544 }
18545
18550 {
18551 basic_json result;
18552
18553 result["copyright"] = "(C) 2013-2022 Niels Lohmann";
18554 result["name"] = "JSON for Modern C++";
18555 result["url"] = "https://github.com/nlohmann/json";
18556 result["version"]["string"] =
18560 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
18561 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
18562 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
18563
18564#ifdef _WIN32
18565 result["platform"] = "win32";
18566#elif defined __linux__
18567 result["platform"] = "linux";
18568#elif defined __APPLE__
18569 result["platform"] = "apple";
18570#elif defined __unix__
18571 result["platform"] = "unix";
18572#else
18573 result["platform"] = "unknown";
18574#endif
18575
18576#if defined(__ICC) || defined(__INTEL_COMPILER)
18577 result["compiler"] = { {"family", "icc"}, {"version", __INTEL_COMPILER} };
18578#elif defined(__clang__)
18579 result["compiler"] = { {"family", "clang"}, {"version", __clang_version__} };
18580#elif defined(__GNUC__) || defined(__GNUG__)
18581 result["compiler"] = { {"family", "gcc"}, {"version", detail::concat(
18582 std::to_string(__GNUC__), '.',
18583 std::to_string(__GNUC_MINOR__), '.',
18584 std::to_string(__GNUC_PATCHLEVEL__))
18585 }
18586 };
18587#elif defined(__HP_cc) || defined(__HP_aCC)
18588 result["compiler"] = "hp"
18589#elif defined(__IBMCPP__)
18590 result["compiler"] = { {"family", "ilecpp"}, {"version", __IBMCPP__} };
18591#elif defined(_MSC_VER)
18592 result["compiler"] = { {"family", "msvc"}, {"version", _MSC_VER} };
18593#elif defined(__PGI)
18594 result["compiler"] = { {"family", "pgcpp"}, {"version", __PGI} };
18595#elif defined(__SUNPRO_CC)
18596 result["compiler"] = { {"family", "sunpro"}, {"version", __SUNPRO_CC} };
18597#else
18598 result["compiler"] = { {"family", "unknown"}, {"version", "unknown"} };
18599#endif
18600
18601
18602#if defined(_MSVC_LANG)
18603 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
18604#elif defined(__cplusplus)
18605 result["compiler"]["c++"] = std::to_string(__cplusplus);
18606#else
18607 result["compiler"]["c++"] = "unknown";
18608#endif
18609 return result;
18610 }
18611
18612
18614 // JSON value data types //
18616
18621
18626#if defined(JSON_HAS_CPP_14)
18627 // use of transparent comparator avoids unnecessary repeated construction of temporaries
18628 // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
18629 using default_object_comparator_t = std::less<>;
18630#else
18631 using default_object_comparator_t = std::less<StringType>;
18632#endif
18633
18636 using object_t = ObjectType<StringType,
18637 basic_json,
18639 AllocatorType<std::pair<const StringType,
18640 basic_json>>>;
18641
18644 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18645
18648 using string_t = StringType;
18649
18652 using boolean_t = BooleanType;
18653
18656 using number_integer_t = NumberIntegerType;
18657
18660 using number_unsigned_t = NumberUnsignedType;
18661
18664 using number_float_t = NumberFloatType;
18665
18669
18673
18675
18676 private:
18677
18679 template<typename T, typename... Args>
18681 static T* create(Args&& ... args)
18682 {
18683 AllocatorType<T> alloc;
18684 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18685
18686 auto deleter = [&](T* obj)
18687 {
18688 AllocatorTraits::deallocate(alloc, obj, 1);
18689 };
18690 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18691 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18692 JSON_ASSERT(obj != nullptr);
18693 return obj.release();
18694 }
18695
18697 // JSON value storage //
18699
18726 union json_value
18727 {
18731 array_t* array;
18733 string_t* string;
18735 binary_t* binary;
18737 boolean_t boolean;
18739 number_integer_t number_integer;
18741 number_unsigned_t number_unsigned;
18743 number_float_t number_float;
18744
18746 json_value() = default;
18748 json_value(boolean_t v) noexcept : boolean(v) {}
18750 json_value(number_integer_t v) noexcept : number_integer(v) {}
18752 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18754 json_value(number_float_t v) noexcept : number_float(v) {}
18756 json_value(value_t t)
18757 {
18758 switch (t)
18759 {
18760 case value_t::object:
18761 {
18762 object = create<object_t>();
18763 break;
18764 }
18765
18766 case value_t::array:
18767 {
18768 array = create<array_t>();
18769 break;
18770 }
18771
18772 case value_t::string:
18773 {
18774 string = create<string_t>("");
18775 break;
18776 }
18777
18778 case value_t::binary:
18779 {
18780 binary = create<binary_t>();
18781 break;
18782 }
18783
18784 case value_t::boolean:
18785 {
18786 boolean = static_cast<boolean_t>(false);
18787 break;
18788 }
18789
18791 {
18792 number_integer = static_cast<number_integer_t>(0);
18793 break;
18794 }
18795
18797 {
18798 number_unsigned = static_cast<number_unsigned_t>(0);
18799 break;
18800 }
18801
18803 {
18804 number_float = static_cast<number_float_t>(0.0);
18805 break;
18806 }
18807
18808 case value_t::null:
18809 {
18810 object = nullptr; // silence warning, see #821
18811 break;
18812 }
18813
18814 case value_t::discarded:
18815 default:
18816 {
18817 object = nullptr; // silence warning, see #821
18819 {
18820 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", nullptr)); // LCOV_EXCL_LINE
18821 }
18822 break;
18823 }
18824 }
18825 }
18826
18828 json_value(const string_t& value) : string(create<string_t>(value)) {}
18829
18831 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
18832
18834 json_value(const object_t& value) : object(create<object_t>(value)) {}
18835
18837 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
18838
18840 json_value(const array_t& value) : array(create<array_t>(value)) {}
18841
18843 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
18844
18846 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
18847
18849 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
18850
18852 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
18853
18855 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
18856
18857 void destroy(value_t t)
18858 {
18859 if (t == value_t::array || t == value_t::object)
18860 {
18861 // flatten the current json_value to a heap-allocated stack
18862 std::vector<basic_json> stack;
18863
18864 // move the top-level items to stack
18865 if (t == value_t::array)
18866 {
18867 stack.reserve(array->size());
18868 std::move(array->begin(), array->end(), std::back_inserter(stack));
18869 }
18870 else
18871 {
18872 stack.reserve(object->size());
18873 for (auto&& it : *object)
18874 {
18875 stack.push_back(std::move(it.second));
18876 }
18877 }
18878
18879 while (!stack.empty())
18880 {
18881 // move the last item to local variable to be processed
18882 basic_json current_item(std::move(stack.back()));
18883 stack.pop_back();
18884
18885 // if current_item is array/object, move
18886 // its children to the stack to be processed later
18887 if (current_item.is_array())
18888 {
18889 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18890
18891 current_item.m_value.array->clear();
18892 }
18893 else if (current_item.is_object())
18894 {
18895 for (auto&& it : *current_item.m_value.object)
18896 {
18897 stack.push_back(std::move(it.second));
18898 }
18899
18900 current_item.m_value.object->clear();
18901 }
18902
18903 // it's now safe that current_item get destructed
18904 // since it doesn't have any children
18905 }
18906 }
18907
18908 switch (t)
18909 {
18910 case value_t::object:
18911 {
18912 AllocatorType<object_t> alloc;
18913 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18914 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18915 break;
18916 }
18917
18918 case value_t::array:
18919 {
18920 AllocatorType<array_t> alloc;
18921 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18922 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18923 break;
18924 }
18925
18926 case value_t::string:
18927 {
18928 AllocatorType<string_t> alloc;
18929 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18930 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18931 break;
18932 }
18933
18934 case value_t::binary:
18935 {
18936 AllocatorType<binary_t> alloc;
18937 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18938 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18939 break;
18940 }
18941
18942 case value_t::null:
18943 case value_t::boolean:
18947 case value_t::discarded:
18948 default:
18949 {
18950 break;
18951 }
18952 }
18953 }
18954 };
18955
18956 private:
18975 void assert_invariant(bool check_parents = true) const noexcept
18976 {
18977 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18978 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18979 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18980 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18981
18982#if JSON_DIAGNOSTICS
18983 JSON_TRY
18984 {
18985 // cppcheck-suppress assertWithSideEffect
18986 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json& j)
18987 {
18988 return j.m_parent == this;
18989 }));
18990 }
18991 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18992#endif
18993 static_cast<void>(check_parents);
18994 }
18995
18996 void set_parents()
18997 {
18998#if JSON_DIAGNOSTICS
18999 switch (m_type)
19000 {
19001 case value_t::array:
19002 {
19003 for (auto& element : *m_value.array)
19004 {
19005 element.m_parent = this;
19006 }
19007 break;
19008 }
19009
19010 case value_t::object:
19011 {
19012 for (auto& element : *m_value.object)
19013 {
19014 element.second.m_parent = this;
19015 }
19016 break;
19017 }
19018
19019 case value_t::null:
19020 case value_t::string:
19021 case value_t::boolean:
19025 case value_t::binary:
19026 case value_t::discarded:
19027 default:
19028 break;
19029 }
19030#endif
19031 }
19032
19033 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
19034 {
19035#if JSON_DIAGNOSTICS
19036 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
19037 {
19038 (it + i)->m_parent = this;
19039 }
19040#else
19041 static_cast<void>(count_set_parents);
19042#endif
19043 return it;
19044 }
19045
19046 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
19047 {
19048#if JSON_DIAGNOSTICS
19049 if (old_capacity != static_cast<std::size_t>(-1))
19050 {
19051 // see https://github.com/nlohmann/json/issues/2838
19053 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
19054 {
19055 // capacity has changed: update all parents
19056 set_parents();
19057 return j;
19058 }
19059 }
19060
19061 // ordered_json uses a vector internally, so pointers could have
19062 // been invalidated; see https://github.com/nlohmann/json/issues/2962
19063#ifdef JSON_HEDLEY_MSVC_VERSION
19064#pragma warning(push )
19065#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19066#endif
19068 {
19069 set_parents();
19070 return j;
19071 }
19072#ifdef JSON_HEDLEY_MSVC_VERSION
19073#pragma warning( pop )
19074#endif
19075
19076 j.m_parent = this;
19077#else
19078 static_cast<void>(j);
19079 static_cast<void>(old_capacity);
19080#endif
19081 return j;
19082 }
19083
19084 public:
19086 // JSON parser callback //
19088
19092
19096
19098 // constructors //
19100
19105
19109 : m_type(v), m_value(v)
19110 {
19111 assert_invariant();
19112 }
19113
19116 basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
19117 : basic_json(value_t::null)
19118 {
19119 assert_invariant();
19120 }
19121
19124 template < typename CompatibleType,
19128 basic_json(CompatibleType&& val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19129 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19130 std::forward<CompatibleType>(val))))
19131 {
19132 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19133 set_parents();
19134 assert_invariant();
19135 }
19136
19139 template < typename BasicJsonType,
19141 detail::is_basic_json<BasicJsonType>::value && !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19142 basic_json(const BasicJsonType& val)
19143 {
19144 using other_boolean_t = typename BasicJsonType::boolean_t;
19145 using other_number_float_t = typename BasicJsonType::number_float_t;
19146 using other_number_integer_t = typename BasicJsonType::number_integer_t;
19147 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19148 using other_string_t = typename BasicJsonType::string_t;
19149 using other_object_t = typename BasicJsonType::object_t;
19150 using other_array_t = typename BasicJsonType::array_t;
19151 using other_binary_t = typename BasicJsonType::binary_t;
19152
19153 switch (val.type())
19154 {
19155 case value_t::boolean:
19156 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19157 break;
19159 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19160 break;
19162 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19163 break;
19165 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19166 break;
19167 case value_t::string:
19168 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19169 break;
19170 case value_t::object:
19171 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19172 break;
19173 case value_t::array:
19174 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19175 break;
19176 case value_t::binary:
19177 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19178 break;
19179 case value_t::null:
19180 *this = nullptr;
19181 break;
19182 case value_t::discarded:
19183 m_type = value_t::discarded;
19184 break;
19185 default: // LCOV_EXCL_LINE
19186 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19187 }
19188 set_parents();
19189 assert_invariant();
19190 }
19191
19195 bool type_deduction = true,
19196 value_t manual_type = value_t::array)
19197 {
19198 // check if each element is an array with two elements whose first
19199 // element is a string
19200 bool is_an_object = std::all_of(init.begin(), init.end(),
19201 [](const detail::json_ref<basic_json>& element_ref)
19202 {
19203 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19204 });
19205
19206 // adjust type if type deduction is not wanted
19207 if (!type_deduction)
19208 {
19209 // if array is wanted, do not create an object though possible
19210 if (manual_type == value_t::array)
19211 {
19212 is_an_object = false;
19213 }
19214
19215 // if object is wanted but impossible, throw an exception
19216 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19217 {
19218 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
19219 }
19220 }
19221
19222 if (is_an_object)
19223 {
19224 // the initializer list is a list of pairs -> create object
19225 m_type = value_t::object;
19227
19228 for (auto& element_ref : init)
19229 {
19230 auto element = element_ref.moved_or_copied();
19231 m_value.object->emplace(
19232 std::move(*((*element.m_value.array)[0].m_value.string)),
19233 std::move((*element.m_value.array)[1]));
19234 }
19235 }
19236 else
19237 {
19238 // the initializer list describes an array -> create array
19239 m_type = value_t::array;
19240 m_value.array = create<array_t>(init.begin(), init.end());
19241 }
19242
19243 set_parents();
19244 assert_invariant();
19245 }
19246
19251 {
19252 auto res = basic_json();
19253 res.m_type = value_t::binary;
19254 res.m_value = init;
19255 return res;
19256 }
19257
19262 {
19263 auto res = basic_json();
19264 res.m_type = value_t::binary;
19265 res.m_value = binary_t(init, subtype);
19266 return res;
19267 }
19268
19273 {
19274 auto res = basic_json();
19275 res.m_type = value_t::binary;
19276 res.m_value = std::move(init);
19277 return res;
19278 }
19279
19284 {
19285 auto res = basic_json();
19286 res.m_type = value_t::binary;
19287 res.m_value = binary_t(std::move(init), subtype);
19288 return res;
19289 }
19290
19295 {
19296 return basic_json(init, false, value_t::array);
19297 }
19298
19303 {
19304 return basic_json(init, false, value_t::object);
19305 }
19306
19310 : m_type(value_t::array)
19311 {
19312 m_value.array = create<array_t>(cnt, val);
19313 set_parents();
19314 assert_invariant();
19315 }
19316
19319 template < class InputIT, typename std::enable_if <
19320 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19321 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19322 basic_json(InputIT first, InputIT last)
19323 {
19324 JSON_ASSERT(first.m_object != nullptr);
19325 JSON_ASSERT(last.m_object != nullptr);
19326
19327 // make sure iterator fits the current value
19328 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19329 {
19330 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
19331 }
19332
19333 // copy type from first iterator
19334 m_type = first.m_object->m_type;
19335
19336 // check if iterator range is complete for primitive values
19337 switch (m_type)
19338 {
19339 case value_t::boolean:
19343 case value_t::string:
19344 {
19345 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19346 || !last.m_it.primitive_iterator.is_end()))
19347 {
19348 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
19349 }
19350 break;
19351 }
19352
19353 case value_t::null:
19354 case value_t::object:
19355 case value_t::array:
19356 case value_t::binary:
19357 case value_t::discarded:
19358 default:
19359 break;
19360 }
19361
19362 switch (m_type)
19363 {
19365 {
19366 m_value.number_integer = first.m_object->m_value.number_integer;
19367 break;
19368 }
19369
19371 {
19372 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19373 break;
19374 }
19375
19377 {
19378 m_value.number_float = first.m_object->m_value.number_float;
19379 break;
19380 }
19381
19382 case value_t::boolean:
19383 {
19384 m_value.boolean = first.m_object->m_value.boolean;
19385 break;
19386 }
19387
19388 case value_t::string:
19389 {
19390 m_value = *first.m_object->m_value.string;
19391 break;
19392 }
19393
19394 case value_t::object:
19395 {
19396 m_value.object = create<object_t>(first.m_it.object_iterator,
19397 last.m_it.object_iterator);
19398 break;
19399 }
19400
19401 case value_t::array:
19402 {
19403 m_value.array = create<array_t>(first.m_it.array_iterator,
19404 last.m_it.array_iterator);
19405 break;
19406 }
19407
19408 case value_t::binary:
19409 {
19410 m_value = *first.m_object->m_value.binary;
19411 break;
19412 }
19413
19414 case value_t::null:
19415 case value_t::discarded:
19416 default:
19417 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
19418 }
19419
19420 set_parents();
19421 assert_invariant();
19422 }
19423
19424
19426 // other constructors and destructor //
19428
19429 template<typename JsonRef,
19431 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19432 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19433
19437 : m_type(other.m_type)
19438 {
19439 // check of passed value is valid
19440 other.assert_invariant();
19441
19442 switch (m_type)
19443 {
19444 case value_t::object:
19445 {
19446 m_value = *other.m_value.object;
19447 break;
19448 }
19449
19450 case value_t::array:
19451 {
19452 m_value = *other.m_value.array;
19453 break;
19454 }
19455
19456 case value_t::string:
19457 {
19458 m_value = *other.m_value.string;
19459 break;
19460 }
19461
19462 case value_t::boolean:
19463 {
19464 m_value = other.m_value.boolean;
19465 break;
19466 }
19467
19469 {
19470 m_value = other.m_value.number_integer;
19471 break;
19472 }
19473
19475 {
19476 m_value = other.m_value.number_unsigned;
19477 break;
19478 }
19479
19481 {
19482 m_value = other.m_value.number_float;
19483 break;
19484 }
19485
19486 case value_t::binary:
19487 {
19488 m_value = *other.m_value.binary;
19489 break;
19490 }
19491
19492 case value_t::null:
19493 case value_t::discarded:
19494 default:
19495 break;
19496 }
19497
19498 set_parents();
19499 assert_invariant();
19500 }
19501
19504 basic_json(basic_json&& other) noexcept
19505 : m_type(std::move(other.m_type)),
19506 m_value(std::move(other.m_value))
19507 {
19508 // check that passed value is valid
19509 other.assert_invariant(false);
19510
19511 // invalidate payload
19512 other.m_type = value_t::null;
19513 other.m_value = {};
19514
19515 set_parents();
19516 assert_invariant();
19517 }
19518
19522 std::is_nothrow_move_constructible<value_t>::value&&
19523 std::is_nothrow_move_assignable<value_t>::value&&
19524 std::is_nothrow_move_constructible<json_value>::value&&
19525 std::is_nothrow_move_assignable<json_value>::value
19526 )
19527 {
19528 // check that passed value is valid
19529 other.assert_invariant();
19530
19531 using std::swap;
19532 swap(m_type, other.m_type);
19533 swap(m_value, other.m_value);
19534
19535 set_parents();
19536 assert_invariant();
19537 return *this;
19538 }
19539
19542 ~basic_json() noexcept
19543 {
19544 assert_invariant(false);
19545 m_value.destroy(m_type);
19546 }
19547
19549
19550 public:
19552 // object inspection //
19554
19558
19561 string_t dump(const int indent = -1,
19562 const char indent_char = ' ',
19563 const bool ensure_ascii = false,
19564 const error_handler_t error_handler = error_handler_t::strict) const
19565 {
19566 string_t result;
19567 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19568
19569 if (indent >= 0)
19570 {
19571 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19572 }
19573 else
19574 {
19575 s.dump(*this, false, ensure_ascii, 0);
19576 }
19577
19578 return result;
19579 }
19580
19583 constexpr value_t type() const noexcept
19584 {
19585 return m_type;
19586 }
19587
19590 constexpr bool is_primitive() const noexcept
19591 {
19592 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19593 }
19594
19597 constexpr bool is_structured() const noexcept
19598 {
19599 return is_array() || is_object();
19600 }
19601
19604 constexpr bool is_null() const noexcept
19605 {
19606 return m_type == value_t::null;
19607 }
19608
19611 constexpr bool is_boolean() const noexcept
19612 {
19613 return m_type == value_t::boolean;
19614 }
19615
19618 constexpr bool is_number() const noexcept
19619 {
19620 return is_number_integer() || is_number_float();
19621 }
19622
19625 constexpr bool is_number_integer() const noexcept
19626 {
19627 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19628 }
19629
19632 constexpr bool is_number_unsigned() const noexcept
19633 {
19634 return m_type == value_t::number_unsigned;
19635 }
19636
19639 constexpr bool is_number_float() const noexcept
19640 {
19641 return m_type == value_t::number_float;
19642 }
19643
19646 constexpr bool is_object() const noexcept
19647 {
19648 return m_type == value_t::object;
19649 }
19650
19653 constexpr bool is_array() const noexcept
19654 {
19655 return m_type == value_t::array;
19656 }
19657
19660 constexpr bool is_string() const noexcept
19661 {
19662 return m_type == value_t::string;
19663 }
19664
19667 constexpr bool is_binary() const noexcept
19668 {
19669 return m_type == value_t::binary;
19670 }
19671
19674 constexpr bool is_discarded() const noexcept
19675 {
19676 return m_type == value_t::discarded;
19677 }
19678
19681 constexpr operator value_t() const noexcept
19682 {
19683 return m_type;
19684 }
19685
19687
19688 private:
19690 // value access //
19692
19694 boolean_t get_impl(boolean_t* /*unused*/) const
19695 {
19697 {
19698 return m_value.boolean;
19699 }
19700
19701 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
19702 }
19703
19705 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19706 {
19707 return is_object() ? m_value.object : nullptr;
19708 }
19709
19711 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19712 {
19713 return is_object() ? m_value.object : nullptr;
19714 }
19715
19717 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19718 {
19719 return is_array() ? m_value.array : nullptr;
19720 }
19721
19723 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19724 {
19725 return is_array() ? m_value.array : nullptr;
19726 }
19727
19729 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19730 {
19731 return is_string() ? m_value.string : nullptr;
19732 }
19733
19735 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19736 {
19737 return is_string() ? m_value.string : nullptr;
19738 }
19739
19741 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19742 {
19743 return is_boolean() ? &m_value.boolean : nullptr;
19744 }
19745
19747 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19748 {
19749 return is_boolean() ? &m_value.boolean : nullptr;
19750 }
19751
19753 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19754 {
19755 return is_number_integer() ? &m_value.number_integer : nullptr;
19756 }
19757
19759 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19760 {
19761 return is_number_integer() ? &m_value.number_integer : nullptr;
19762 }
19763
19765 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19766 {
19767 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19768 }
19769
19771 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19772 {
19773 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19774 }
19775
19777 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19778 {
19779 return is_number_float() ? &m_value.number_float : nullptr;
19780 }
19781
19783 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19784 {
19785 return is_number_float() ? &m_value.number_float : nullptr;
19786 }
19787
19789 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19790 {
19791 return is_binary() ? m_value.binary : nullptr;
19792 }
19793
19795 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19796 {
19797 return is_binary() ? m_value.binary : nullptr;
19798 }
19799
19811 template<typename ReferenceType, typename ThisType>
19812 static ReferenceType get_ref_impl(ThisType& obj)
19813 {
19814 // delegate the call to get_ptr<>()
19815 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19816
19817 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19818 {
19819 return *ptr;
19820 }
19821
19822 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
19823 }
19824
19825 public:
19829
19832 template<typename PointerType, typename std::enable_if<
19833 std::is_pointer<PointerType>::value, int>::type = 0>
19834 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19835 {
19836 // delegate the call to get_impl_ptr<>()
19837 return get_impl_ptr(static_cast<PointerType>(nullptr));
19838 }
19839
19842 template < typename PointerType, typename std::enable_if <
19843 std::is_pointer<PointerType>::value&&
19844 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19845 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19846 {
19847 // delegate the call to get_impl_ptr<>() const
19848 return get_impl_ptr(static_cast<PointerType>(nullptr));
19849 }
19850
19851 private:
19890 template < typename ValueType,
19894 int > = 0 >
19895 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
19896 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19897 {
19898 auto ret = ValueType();
19900 return ret;
19901 }
19902
19933 template < typename ValueType,
19935 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19936 int > = 0 >
19937 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
19938 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19939 {
19941 }
19942
19958 template < typename BasicJsonType,
19960 detail::is_basic_json<BasicJsonType>::value,
19961 int > = 0 >
19962 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
19963 {
19964 return *this;
19965 }
19966
19981 template<typename BasicJsonType,
19983 std::is_same<BasicJsonType, basic_json_t>::value,
19984 int> = 0>
19985 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
19986 {
19987 return *this;
19988 }
19989
19994 template<typename PointerType,
19996 std::is_pointer<PointerType>::value,
19997 int> = 0>
19998 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
19999 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20000 {
20001 // delegate the call to get_ptr
20002 return get_ptr<PointerType>();
20003 }
20004
20005 public:
20029 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20030#if defined(JSON_HAS_CPP_14)
20031 constexpr
20032#endif
20033 auto get() const noexcept(
20034 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20035 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20036 {
20037 // we cannot static_assert on ValueTypeCV being non-const, because
20038 // there is support for get<const basic_json_t>(), which is why we
20039 // still need the uncvref
20040 static_assert(!std::is_reference<ValueTypeCV>::value,
20041 "get() cannot be used with reference types, you might want to use get_ref()");
20042 return get_impl<ValueType>(detail::priority_tag<4> {});
20043 }
20044
20072 template<typename PointerType, typename std::enable_if<
20073 std::is_pointer<PointerType>::value, int>::type = 0>
20074 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20075 {
20076 // delegate the call to get_ptr
20077 return get_ptr<PointerType>();
20078 }
20079
20082 template < typename ValueType,
20086 int > = 0 >
20087 ValueType& get_to(ValueType& v) const noexcept(noexcept(
20088 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20089 {
20091 return v;
20092 }
20093
20094 // specialization to allow calling get_to with a basic_json value
20095 // see https://github.com/nlohmann/json/issues/2175
20096 template<typename ValueType,
20099 int> = 0>
20100 ValueType& get_to(ValueType& v) const
20101 {
20102 v = *this;
20103 return v;
20104 }
20105
20106 template <
20107 typename T, std::size_t N,
20108 typename Array = T(&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20111 Array get_to(T(&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20112 noexcept(noexcept(JSONSerializer<Array>::from_json(
20113 std::declval<const basic_json_t&>(), v)))
20114 {
20116 return v;
20117 }
20118
20121 template<typename ReferenceType, typename std::enable_if<
20122 std::is_reference<ReferenceType>::value, int>::type = 0>
20123 ReferenceType get_ref()
20124 {
20125 // delegate call to get_ref_impl
20126 return get_ref_impl<ReferenceType>(*this);
20127 }
20128
20131 template < typename ReferenceType, typename std::enable_if <
20132 std::is_reference<ReferenceType>::value&&
20133 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20134 ReferenceType get_ref() const
20135 {
20136 // delegate call to get_ref_impl
20137 return get_ref_impl<ReferenceType>(*this);
20138 }
20139
20169 template < typename ValueType, typename std::enable_if <
20177#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20179#endif
20180#if defined(JSON_HAS_CPP_17)
20182#endif
20184 >::value, int >::type = 0 >
20185 JSON_EXPLICIT operator ValueType() const
20186 {
20187 // delegate the call to get<>() const
20188 return get<ValueType>();
20189 }
20190
20194 {
20195 if (!is_binary())
20196 {
20197 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20198 }
20199
20200 return *get_ptr<binary_t*>();
20201 }
20202
20205 const binary_t& get_binary() const
20206 {
20207 if (!is_binary())
20208 {
20209 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20210 }
20211
20212 return *get_ptr<const binary_t*>();
20213 }
20214
20216
20217
20219 // element access //
20221
20225
20229 {
20230 // at only works for arrays
20232 {
20233 JSON_TRY
20234 {
20235 return set_parent(m_value.array->at(idx));
20236 }
20237 JSON_CATCH(std::out_of_range&)
20238 {
20239 // create better exception explanation
20240 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20241 }
20242 }
20243 else
20244 {
20245 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20246 }
20247 }
20248
20252 {
20253 // at only works for arrays
20255 {
20256 JSON_TRY
20257 {
20258 return m_value.array->at(idx);
20259 }
20260 JSON_CATCH(std::out_of_range&)
20261 {
20262 // create better exception explanation
20263 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20264 }
20265 }
20266 else
20267 {
20268 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20269 }
20270 }
20271
20274 reference at(const typename object_t::key_type& key)
20275 {
20276 // at only works for objects
20278 {
20279 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20280 }
20281
20282 auto it = m_value.object->find(key);
20283 if (it == m_value.object->end())
20284 {
20285 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20286 }
20287 return set_parent(it->second);
20288 }
20289
20292 template<class KeyType, detail::enable_if_t<
20294 reference at(KeyType&& key)
20295 {
20296 // at only works for objects
20298 {
20299 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20300 }
20301
20302 auto it = m_value.object->find(std::forward<KeyType>(key));
20303 if (it == m_value.object->end())
20304 {
20305 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20306 }
20307 return set_parent(it->second);
20308 }
20309
20312 const_reference at(const typename object_t::key_type& key) const
20313 {
20314 // at only works for objects
20316 {
20317 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20318 }
20319
20320 auto it = m_value.object->find(key);
20321 if (it == m_value.object->end())
20322 {
20323 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20324 }
20325 return it->second;
20326 }
20327
20330 template<class KeyType, detail::enable_if_t<
20332 const_reference at(KeyType&& key) const
20333 {
20334 // at only works for objects
20336 {
20337 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20338 }
20339
20340 auto it = m_value.object->find(std::forward<KeyType>(key));
20341 if (it == m_value.object->end())
20342 {
20343 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20344 }
20345 return it->second;
20346 }
20347
20351 {
20352 // implicitly convert null value to an empty array
20353 if (is_null())
20354 {
20355 m_type = value_t::array;
20356 m_value.array = create<array_t>();
20357 assert_invariant();
20358 }
20359
20360 // operator[] only works for arrays
20362 {
20363 // fill up array with null values if given idx is outside range
20364 if (idx >= m_value.array->size())
20365 {
20366#if JSON_DIAGNOSTICS
20367 // remember array size & capacity before resizing
20368 const auto old_size = m_value.array->size();
20369 const auto old_capacity = m_value.array->capacity();
20370#endif
20371 m_value.array->resize(idx + 1);
20372
20373#if JSON_DIAGNOSTICS
20374 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
20375 {
20376 // capacity has changed: update all parents
20377 set_parents();
20378 }
20379 else
20380 {
20381 // set parent for values added above
20382 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
20383 }
20384#endif
20385 assert_invariant();
20386 }
20387
20388 return m_value.array->operator[](idx);
20389 }
20390
20391 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20392 }
20393
20397 {
20398 // const operator[] only works for arrays
20400 {
20401 return m_value.array->operator[](idx);
20402 }
20403
20404 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20405 }
20406
20409 reference operator[](typename object_t::key_type key)
20410 {
20411 // implicitly convert null value to an empty object
20412 if (is_null())
20413 {
20414 m_type = value_t::object;
20415 m_value.object = create<object_t>();
20416 assert_invariant();
20417 }
20418
20419 // operator[] only works for objects
20421 {
20422 auto result = m_value.object->emplace(std::move(key), nullptr);
20423 return set_parent(result.first->second);
20424 }
20425
20426 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20427 }
20428
20431 const_reference operator[](const typename object_t::key_type& key) const
20432 {
20433 // const operator[] only works for objects
20435 {
20436 auto it = m_value.object->find(key);
20437 JSON_ASSERT(it != m_value.object->end());
20438 return it->second;
20439 }
20440
20441 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20442 }
20443
20444 // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
20445 // (they seemingly cannot be constrained to resolve the ambiguity)
20446 template<typename T>
20448 {
20449 return operator[](typename object_t::key_type(key));
20450 }
20451
20452 template<typename T>
20454 {
20455 return operator[](typename object_t::key_type(key));
20456 }
20457
20460 template<class KeyType, detail::enable_if_t<
20462 reference operator[](KeyType&& key)
20463 {
20464 // implicitly convert null value to an empty object
20465 if (is_null())
20466 {
20467 m_type = value_t::object;
20468 m_value.object = create<object_t>();
20469 assert_invariant();
20470 }
20471
20472 // operator[] only works for objects
20474 {
20475 auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
20476 return set_parent(result.first->second);
20477 }
20478
20479 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20480 }
20481
20484 template<class KeyType, detail::enable_if_t<
20486 const_reference operator[](KeyType&& key) const
20487 {
20488 // const operator[] only works for objects
20490 {
20491 auto it = m_value.object->find(std::forward<KeyType>(key));
20492 JSON_ASSERT(it != m_value.object->end());
20493 return it->second;
20494 }
20495
20496 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20497 }
20498
20501 // this is the value(const typename object_t::key_type&) overload
20502 template < class KeyType, class ValueType, detail::enable_if_t <
20503 std::is_same<KeyType, typename object_t::key_type>::value
20505 && !std::is_same<value_t, ValueType>::value, int > = 0 >
20506 typename std::decay<ValueType>::type value(const KeyType& key, ValueType&& default_value) const
20507 {
20508 // value only works for objects
20510 {
20511 // if key is found, return value and given default value otherwise
20512 const auto it = find(key);
20513 if (it != end())
20514 {
20515 return it->template get<typename std::decay<ValueType>::type>();
20516 }
20517
20518 return std::forward<ValueType>(default_value);
20519 }
20520
20521 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20522 }
20523
20527 string_t value(const typename object_t::key_type& key, const char* default_value) const
20528 {
20529 return value(key, string_t(default_value));
20530 }
20531
20532 // these two functions, in conjunction with value(const KeyType &, ValueType &&),
20533 // resolve an ambiguity that would otherwise occur between the json_pointer and
20534 // typename object_t::key_type & overloads
20535 template < class ValueType, detail::enable_if_t <
20537 && !std::is_same<value_t, ValueType>::value, int > = 0 >
20538 typename std::decay<ValueType>::type value(const char* key, ValueType&& default_value) const
20539 {
20540 return value(typename object_t::key_type(key), std::forward<ValueType>(default_value));
20541 }
20542
20543 string_t value(const char* key, const char* default_value) const
20544 {
20545 return value(typename object_t::key_type(key), string_t(default_value));
20546 }
20547
20551 template < class KeyType, class ValueType, detail::enable_if_t <
20553 && !std::is_same<value_t, ValueType>::value
20555 typename std::decay<ValueType>::type value(KeyType&& key, ValueType&& default_value) const
20556 {
20557 // value only works for objects
20559 {
20560 // if key is found, return value and given default value otherwise
20561 const auto it = find(std::forward<KeyType>(key));
20562 if (it != end())
20563 {
20564 return it->template get<typename std::decay<ValueType>::type>();
20565 }
20566
20567 return std::forward<ValueType>(default_value);
20568 }
20569
20570 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20571 }
20572
20576 template < class KeyType, detail::enable_if_t <
20578 string_t value(KeyType&& key, const char* default_value) const
20579 {
20580 return value(std::forward<KeyType>(key), string_t(default_value));
20581 }
20582
20585 template < class ValueType, detail::enable_if_t <
20587 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20588 {
20589 // value only works for objects
20591 {
20592 // if pointer resolves a value, return it or use default value
20593 JSON_TRY
20594 {
20595 return ptr.get_checked(this).template get<ValueType>();
20596 }
20598 {
20599 return default_value;
20600 }
20601 }
20602
20603 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20604 }
20605
20606 template < class ValueType, class BasicJsonType, detail::enable_if_t <
20609 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
20610 {
20611 return value(ptr.convert(), default_value);
20612 }
20613
20618 string_t value(const json_pointer& ptr, const char* default_value) const
20619 {
20620 return value(ptr, string_t(default_value));
20621 }
20622
20623 template<typename BasicJsonType>
20626 string_t value(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr, const char* default_value) const
20627 {
20628 return value(ptr.convert(), default_value);
20629 }
20630
20634 {
20635 return *begin();
20636 }
20637
20641 {
20642 return *cbegin();
20643 }
20644
20648 {
20649 auto tmp = end();
20650 --tmp;
20651 return *tmp;
20652 }
20653
20657 {
20658 auto tmp = cend();
20659 --tmp;
20660 return *tmp;
20661 }
20662
20665 template < class IteratorType, detail::enable_if_t <
20666 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20667 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20668 IteratorType erase(IteratorType pos)
20669 {
20670 // make sure iterator fits the current value
20671 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20672 {
20673 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
20674 }
20675
20676 IteratorType result = end();
20677
20678 switch (m_type)
20679 {
20680 case value_t::boolean:
20684 case value_t::string:
20685 case value_t::binary:
20686 {
20687 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20688 {
20689 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
20690 }
20691
20692 if (is_string())
20693 {
20694 AllocatorType<string_t> alloc;
20695 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20696 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20697 m_value.string = nullptr;
20698 }
20699 else if (is_binary())
20700 {
20701 AllocatorType<binary_t> alloc;
20702 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20703 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20704 m_value.binary = nullptr;
20705 }
20706
20707 m_type = value_t::null;
20708 assert_invariant();
20709 break;
20710 }
20711
20712 case value_t::object:
20713 {
20714 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20715 break;
20716 }
20717
20718 case value_t::array:
20719 {
20720 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20721 break;
20722 }
20723
20724 case value_t::null:
20725 case value_t::discarded:
20726 default:
20727 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20728 }
20729
20730 return result;
20731 }
20732
20735 template < class IteratorType, detail::enable_if_t <
20736 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20737 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20738 IteratorType erase(IteratorType first, IteratorType last)
20739 {
20740 // make sure iterator fits the current value
20741 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20742 {
20743 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
20744 }
20745
20746 IteratorType result = end();
20747
20748 switch (m_type)
20749 {
20750 case value_t::boolean:
20754 case value_t::string:
20755 case value_t::binary:
20756 {
20757 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20758 || !last.m_it.primitive_iterator.is_end()))
20759 {
20760 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
20761 }
20762
20763 if (is_string())
20764 {
20765 AllocatorType<string_t> alloc;
20766 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20767 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20768 m_value.string = nullptr;
20769 }
20770 else if (is_binary())
20771 {
20772 AllocatorType<binary_t> alloc;
20773 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20774 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20775 m_value.binary = nullptr;
20776 }
20777
20778 m_type = value_t::null;
20779 assert_invariant();
20780 break;
20781 }
20782
20783 case value_t::object:
20784 {
20785 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20786 last.m_it.object_iterator);
20787 break;
20788 }
20789
20790 case value_t::array:
20791 {
20792 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20793 last.m_it.array_iterator);
20794 break;
20795 }
20796
20797 case value_t::null:
20798 case value_t::discarded:
20799 default:
20800 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20801 }
20802
20803 return result;
20804 }
20805
20806 private:
20807 template < typename KeyType, detail::enable_if_t <
20809 size_type erase_internal(KeyType&& key)
20810 {
20811 // this erase only works for objects
20813 {
20814 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20815 }
20816
20817 return m_value.object->erase(std::forward<KeyType>(key));
20818 }
20819
20820 template < typename KeyType, detail::enable_if_t <
20821 !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
20822 size_type erase_internal(KeyType&& key)
20823 {
20824 // this erase only works for objects
20826 {
20827 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20828 }
20829
20830 const auto it = m_value.object->find(std::forward<KeyType>(key));
20831 if (it != m_value.object->end())
20832 {
20833 m_value.object->erase(it);
20834 return 1;
20835 }
20836 return 0;
20837 }
20838
20839 public:
20840
20843 size_type erase(const typename object_t::key_type& key)
20844 {
20845 // the indirection via erase_internal() is added to avoid making this
20846 // function a template and thus de-rank it during overload resolution
20847 return erase_internal(key);
20848 }
20849
20852 template<class KeyType, detail::enable_if_t<
20854 size_type erase(KeyType&& key)
20855 {
20856 return erase_internal(std::forward<KeyType>(key));
20857 }
20858
20861 void erase(const size_type idx)
20862 {
20863 // this erase only works for arrays
20865 {
20866 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20867 {
20868 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20869 }
20870
20871 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20872 }
20873 else
20874 {
20875 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20876 }
20877 }
20878
20880
20881
20883 // lookup //
20885
20888
20891 iterator find(const typename object_t::key_type& key)
20892 {
20893 auto result = end();
20894
20895 if (is_object())
20896 {
20897 result.m_it.object_iterator = m_value.object->find(key);
20898 }
20899
20900 return result;
20901 }
20902
20905 const_iterator find(const typename object_t::key_type& key) const
20906 {
20907 auto result = cend();
20908
20909 if (is_object())
20910 {
20911 result.m_it.object_iterator = m_value.object->find(key);
20912 }
20913
20914 return result;
20915 }
20916
20919 template<class KeyType, detail::enable_if_t<
20921 iterator find(KeyType&& key)
20922 {
20923 auto result = end();
20924
20925 if (is_object())
20926 {
20927 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
20928 }
20929
20930 return result;
20931 }
20932
20935 template<class KeyType, detail::enable_if_t<
20937 const_iterator find(KeyType&& key) const
20938 {
20939 auto result = cend();
20940
20941 if (is_object())
20942 {
20943 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
20944 }
20945
20946 return result;
20947 }
20948
20951 size_type count(const typename object_t::key_type& key) const
20952 {
20953 // return 0 for all nonobject types
20954 return is_object() ? m_value.object->count(key) : 0;
20955 }
20956
20959 template<class KeyType, detail::enable_if_t<
20961 size_type count(KeyType&& key) const
20962 {
20963 // return 0 for all nonobject types
20964 return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
20965 }
20966
20969 bool contains(const typename object_t::key_type& key) const
20970 {
20971 return is_object() && m_value.object->find(key) != m_value.object->end();
20972 }
20973
20976 template<class KeyType, detail::enable_if_t<
20978 bool contains(KeyType&& key) const
20979 {
20980 return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
20981 }
20982
20985 bool contains(const json_pointer& ptr) const
20986 {
20987 return ptr.contains(this);
20988 }
20989
20990 template<typename BasicJsonType>
20992 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType> ptr) const
20993 {
20994 return ptr.contains(this);
20995 }
20996
20998
20999
21001 // iterators //
21003
21006
21009 iterator begin() noexcept
21010 {
21011 iterator result(this);
21012 result.set_begin();
21013 return result;
21014 }
21015
21018 const_iterator begin() const noexcept
21019 {
21020 return cbegin();
21021 }
21022
21025 const_iterator cbegin() const noexcept
21026 {
21027 const_iterator result(this);
21028 result.set_begin();
21029 return result;
21030 }
21031
21034 iterator end() noexcept
21035 {
21036 iterator result(this);
21037 result.set_end();
21038 return result;
21039 }
21040
21043 const_iterator end() const noexcept
21044 {
21045 return cend();
21046 }
21047
21050 const_iterator cend() const noexcept
21051 {
21052 const_iterator result(this);
21053 result.set_end();
21054 return result;
21055 }
21056
21059 reverse_iterator rbegin() noexcept
21060 {
21061 return reverse_iterator(end());
21062 }
21063
21066 const_reverse_iterator rbegin() const noexcept
21067 {
21068 return crbegin();
21069 }
21070
21073 reverse_iterator rend() noexcept
21074 {
21075 return reverse_iterator(begin());
21076 }
21077
21080 const_reverse_iterator rend() const noexcept
21081 {
21082 return crend();
21083 }
21084
21087 const_reverse_iterator crbegin() const noexcept
21088 {
21089 return const_reverse_iterator(cend());
21090 }
21091
21094 const_reverse_iterator crend() const noexcept
21095 {
21096 return const_reverse_iterator(cbegin());
21097 }
21098
21099 public:
21105 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21106 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21107 {
21108 return ref.items();
21109 }
21110
21116 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21117 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21118 {
21119 return ref.items();
21120 }
21121
21124 iteration_proxy<iterator> items() noexcept
21125 {
21126 return iteration_proxy<iterator>(*this);
21127 }
21128
21131 iteration_proxy<const_iterator> items() const noexcept
21132 {
21133 return iteration_proxy<const_iterator>(*this);
21134 }
21135
21137
21138
21140 // capacity //
21142
21145
21148 bool empty() const noexcept
21149 {
21150 switch (m_type)
21151 {
21152 case value_t::null:
21153 {
21154 // null values are empty
21155 return true;
21156 }
21157
21158 case value_t::array:
21159 {
21160 // delegate call to array_t::empty()
21161 return m_value.array->empty();
21162 }
21163
21164 case value_t::object:
21165 {
21166 // delegate call to object_t::empty()
21167 return m_value.object->empty();
21168 }
21169
21170 case value_t::string:
21171 case value_t::boolean:
21175 case value_t::binary:
21176 case value_t::discarded:
21177 default:
21178 {
21179 // all other types are nonempty
21180 return false;
21181 }
21182 }
21183 }
21184
21187 size_type size() const noexcept
21188 {
21189 switch (m_type)
21190 {
21191 case value_t::null:
21192 {
21193 // null values are empty
21194 return 0;
21195 }
21196
21197 case value_t::array:
21198 {
21199 // delegate call to array_t::size()
21200 return m_value.array->size();
21201 }
21202
21203 case value_t::object:
21204 {
21205 // delegate call to object_t::size()
21206 return m_value.object->size();
21207 }
21208
21209 case value_t::string:
21210 case value_t::boolean:
21214 case value_t::binary:
21215 case value_t::discarded:
21216 default:
21217 {
21218 // all other types have size 1
21219 return 1;
21220 }
21221 }
21222 }
21223
21226 size_type max_size() const noexcept
21227 {
21228 switch (m_type)
21229 {
21230 case value_t::array:
21231 {
21232 // delegate call to array_t::max_size()
21233 return m_value.array->max_size();
21234 }
21235
21236 case value_t::object:
21237 {
21238 // delegate call to object_t::max_size()
21239 return m_value.object->max_size();
21240 }
21241
21242 case value_t::null:
21243 case value_t::string:
21244 case value_t::boolean:
21248 case value_t::binary:
21249 case value_t::discarded:
21250 default:
21251 {
21252 // all other types have max_size() == size()
21253 return size();
21254 }
21255 }
21256 }
21257
21259
21260
21262 // modifiers //
21264
21267
21270 void clear() noexcept
21271 {
21272 switch (m_type)
21273 {
21275 {
21276 m_value.number_integer = 0;
21277 break;
21278 }
21279
21281 {
21282 m_value.number_unsigned = 0;
21283 break;
21284 }
21285
21287 {
21288 m_value.number_float = 0.0;
21289 break;
21290 }
21291
21292 case value_t::boolean:
21293 {
21294 m_value.boolean = false;
21295 break;
21296 }
21297
21298 case value_t::string:
21299 {
21300 m_value.string->clear();
21301 break;
21302 }
21303
21304 case value_t::binary:
21305 {
21306 m_value.binary->clear();
21307 break;
21308 }
21309
21310 case value_t::array:
21311 {
21312 m_value.array->clear();
21313 break;
21314 }
21315
21316 case value_t::object:
21317 {
21318 m_value.object->clear();
21319 break;
21320 }
21321
21322 case value_t::null:
21323 case value_t::discarded:
21324 default:
21325 break;
21326 }
21327 }
21328
21331 void push_back(basic_json&& val)
21332 {
21333 // push_back only works for null objects or arrays
21334 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21335 {
21336 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21337 }
21338
21339 // transform null object into an array
21340 if (is_null())
21341 {
21342 m_type = value_t::array;
21344 assert_invariant();
21345 }
21346
21347 // add element to array (move semantics)
21348 const auto old_capacity = m_value.array->capacity();
21349 m_value.array->push_back(std::move(val));
21350 set_parent(m_value.array->back(), old_capacity);
21351 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
21352 }
21353
21357 {
21358 push_back(std::move(val));
21359 return *this;
21360 }
21361
21364 void push_back(const basic_json& val)
21365 {
21366 // push_back only works for null objects or arrays
21367 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21368 {
21369 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21370 }
21371
21372 // transform null object into an array
21373 if (is_null())
21374 {
21375 m_type = value_t::array;
21377 assert_invariant();
21378 }
21379
21380 // add element to array
21381 const auto old_capacity = m_value.array->capacity();
21382 m_value.array->push_back(val);
21383 set_parent(m_value.array->back(), old_capacity);
21384 }
21385
21389 {
21390 push_back(val);
21391 return *this;
21392 }
21393
21396 void push_back(const typename object_t::value_type& val)
21397 {
21398 // push_back only works for null objects or objects
21399 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21400 {
21401 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21402 }
21403
21404 // transform null object into an object
21405 if (is_null())
21406 {
21407 m_type = value_t::object;
21409 assert_invariant();
21410 }
21411
21412 // add element to object
21413 auto res = m_value.object->insert(val);
21414 set_parent(res.first->second);
21415 }
21416
21419 reference operator+=(const typename object_t::value_type& val)
21420 {
21421 push_back(val);
21422 return *this;
21423 }
21424
21428 {
21429 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21430 {
21431 basic_json&& key = init.begin()->moved_or_copied();
21432 push_back(typename object_t::value_type(
21433 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21434 }
21435 else
21436 {
21438 }
21439 }
21440
21444 {
21445 push_back(init);
21446 return *this;
21447 }
21448
21451 template<class... Args>
21452 reference emplace_back(Args&& ... args)
21453 {
21454 // emplace_back only works for null objects or arrays
21455 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21456 {
21457 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
21458 }
21459
21460 // transform null object into an array
21461 if (is_null())
21462 {
21463 m_type = value_t::array;
21465 assert_invariant();
21466 }
21467
21468 // add element to array (perfect forwarding)
21469 const auto old_capacity = m_value.array->capacity();
21470 m_value.array->emplace_back(std::forward<Args>(args)...);
21471 return set_parent(m_value.array->back(), old_capacity);
21472 }
21473
21476 template<class... Args>
21477 std::pair<iterator, bool> emplace(Args&& ... args)
21478 {
21479 // emplace only works for null objects or arrays
21480 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21481 {
21482 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
21483 }
21484
21485 // transform null object into an object
21486 if (is_null())
21487 {
21488 m_type = value_t::object;
21490 assert_invariant();
21491 }
21492
21493 // add element to array (perfect forwarding)
21494 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21495 set_parent(res.first->second);
21496
21497 // create result iterator and set iterator to the result of emplace
21498 auto it = begin();
21499 it.m_it.object_iterator = res.first;
21500
21501 // return pair of iterator and boolean
21502 return { it, res.second };
21503 }
21504
21508 template<typename... Args>
21510 {
21511 iterator result(this);
21512 JSON_ASSERT(m_value.array != nullptr);
21513
21514 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21515 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21516 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21517
21518 // This could have been written as:
21519 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21520 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21521
21522 set_parents();
21523 return result;
21524 }
21525
21529 {
21530 // insert only works for arrays
21532 {
21533 // check if iterator pos fits to this JSON value
21534 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21535 {
21536 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21537 }
21538
21539 // insert to array and return iterator
21540 return insert_iterator(pos, val);
21541 }
21542
21543 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21544 }
21545
21549 {
21550 return insert(pos, val);
21551 }
21552
21556 {
21557 // insert only works for arrays
21559 {
21560 // check if iterator pos fits to this JSON value
21561 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21562 {
21563 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21564 }
21565
21566 // insert to array and return iterator
21567 return insert_iterator(pos, cnt, val);
21568 }
21569
21570 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21571 }
21572
21576 {
21577 // insert only works for arrays
21579 {
21580 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21581 }
21582
21583 // check if iterator pos fits to this JSON value
21584 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21585 {
21586 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21587 }
21588
21589 // check if range iterators belong to the same JSON object
21590 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21591 {
21592 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21593 }
21594
21595 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
21596 {
21597 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
21598 }
21599
21600 // insert to array and return iterator
21601 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21602 }
21603
21607 {
21608 // insert only works for arrays
21610 {
21611 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21612 }
21613
21614 // check if iterator pos fits to this JSON value
21615 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21616 {
21617 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21618 }
21619
21620 // insert to array and return iterator
21621 return insert_iterator(pos, ilist.begin(), ilist.end());
21622 }
21623
21627 {
21628 // insert only works for objects
21630 {
21631 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21632 }
21633
21634 // check if range iterators belong to the same JSON object
21635 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21636 {
21637 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21638 }
21639
21640 // passed iterators must belong to objects
21641 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21642 {
21643 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
21644 }
21645
21646 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21647 }
21648
21651 void update(const_reference j, bool merge_objects = false)
21652 {
21653 update(j.begin(), j.end(), merge_objects);
21654 }
21655
21658 void update(const_iterator first, const_iterator last, bool merge_objects = false)
21659 {
21660 // implicitly convert null value to an empty object
21661 if (is_null())
21662 {
21663 m_type = value_t::object;
21664 m_value.object = create<object_t>();
21665 assert_invariant();
21666 }
21667
21669 {
21670 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
21671 }
21672
21673 // check if range iterators belong to the same JSON object
21674 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21675 {
21676 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21677 }
21678
21679 // passed iterators must belong to objects
21680 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21681 {
21682 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
21683 }
21684
21685 for (auto it = first; it != last; ++it)
21686 {
21687 if (merge_objects && it.value().is_object())
21688 {
21689 auto it2 = m_value.object->find(it.key());
21690 if (it2 != m_value.object->end())
21691 {
21692 it2->second.update(it.value(), true);
21693 continue;
21694 }
21695 }
21696 m_value.object->operator[](it.key()) = it.value();
21697#if JSON_DIAGNOSTICS
21698 m_value.object->operator[](it.key()).m_parent = this;
21699#endif
21700 }
21701 }
21702
21705 void swap(reference other) noexcept (
21706 std::is_nothrow_move_constructible<value_t>::value&&
21707 std::is_nothrow_move_assignable<value_t>::value&&
21708 std::is_nothrow_move_constructible<json_value>::value&&
21709 std::is_nothrow_move_assignable<json_value>::value
21710 )
21711 {
21712 std::swap(m_type, other.m_type);
21713 std::swap(m_value, other.m_value);
21714
21715 set_parents();
21716 other.set_parents();
21717 assert_invariant();
21718 }
21719
21722 friend void swap(reference left, reference right) noexcept (
21723 std::is_nothrow_move_constructible<value_t>::value&&
21724 std::is_nothrow_move_assignable<value_t>::value&&
21725 std::is_nothrow_move_constructible<json_value>::value&&
21726 std::is_nothrow_move_assignable<json_value>::value
21727 )
21728 {
21729 left.swap(right);
21730 }
21731
21734 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
21735 {
21736 // swap only works for arrays
21738 {
21739 std::swap(*(m_value.array), other);
21740 }
21741 else
21742 {
21743 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21744 }
21745 }
21746
21749 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
21750 {
21751 // swap only works for objects
21753 {
21754 std::swap(*(m_value.object), other);
21755 }
21756 else
21757 {
21758 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21759 }
21760 }
21761
21764 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
21765 {
21766 // swap only works for strings
21768 {
21769 std::swap(*(m_value.string), other);
21770 }
21771 else
21772 {
21773 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21774 }
21775 }
21776
21779 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
21780 {
21781 // swap only works for strings
21783 {
21784 std::swap(*(m_value.binary), other);
21785 }
21786 else
21787 {
21788 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21789 }
21790 }
21791
21794 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
21795 {
21796 // swap only works for strings
21798 {
21799 std::swap(*(m_value.binary), other);
21800 }
21801 else
21802 {
21803 JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21804 }
21805 }
21806
21808
21810 // lexicographical comparison operators //
21812
21815
21816 // note parentheses around operands are necessary; see
21817 // https://github.com/nlohmann/json/issues/1530
21818#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
21819 const auto lhs_type = lhs.type(); \
21820 const auto rhs_type = rhs.type(); \
21821 \
21822 if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
21823 { \
21824 switch (lhs_type) \
21825 { \
21826 case value_t::array: \
21827 return (*lhs.m_value.array) op (*rhs.m_value.array); \
21828 \
21829 case value_t::object: \
21830 return (*lhs.m_value.object) op (*rhs.m_value.object); \
21831 \
21832 case value_t::null: \
21833 return (null_result); \
21834 \
21835 case value_t::string: \
21836 return (*lhs.m_value.string) op (*rhs.m_value.string); \
21837 \
21838 case value_t::boolean: \
21839 return (lhs.m_value.boolean) op (rhs.m_value.boolean); \
21840 \
21841 case value_t::number_integer: \
21842 return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \
21843 \
21844 case value_t::number_unsigned: \
21845 return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \
21846 \
21847 case value_t::number_float: \
21848 return (lhs.m_value.number_float) op (rhs.m_value.number_float); \
21849 \
21850 case value_t::binary: \
21851 return (*lhs.m_value.binary) op (*rhs.m_value.binary); \
21852 \
21853 case value_t::discarded: \
21854 default: \
21855 return (unordered_result); \
21856 } \
21857 } \
21858 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
21859 { \
21860 return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \
21861 } \
21862 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
21863 { \
21864 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \
21865 } \
21866 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
21867 { \
21868 return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \
21869 } \
21870 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
21871 { \
21872 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \
21873 } \
21874 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
21875 { \
21876 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \
21877 } \
21878 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
21879 { \
21880 return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \
21881 } \
21882 else if(compares_unordered(lhs, rhs))\
21883 {\
21884 return (unordered_result);\
21885 }\
21886 \
21887 return (default_result);
21888
21890 // returns true if:
21891 // - any operand is NaN and the other operand is of number type
21892 // - any operand is discarded
21893 // in legacy mode, discarded values are considered ordered if
21894 // an operation is computed as an odd number of inverses of others
21895 static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
21896 {
21897 if ((lhs.is_number_float() && std::isnan(lhs.m_value.number_float) && rhs.is_number())
21898 || (rhs.is_number_float() && std::isnan(rhs.m_value.number_float) && lhs.is_number()))
21899 {
21900 return true;
21901 }
21902#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
21903 return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
21904#else
21905 static_cast<void>(inverse);
21906 return lhs.is_discarded() || rhs.is_discarded();
21907#endif
21908 }
21909
21910 private:
21911 bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
21912 {
21913 return compares_unordered(*this, rhs, inverse);
21914 }
21915
21916 public:
21917#if JSON_HAS_THREE_WAY_COMPARISON
21920 bool operator==(const_reference rhs) const noexcept
21921 {
21922#ifdef __GNUC__
21923#pragma GCC diagnostic push
21924#pragma GCC diagnostic ignored "-Wfloat-equal"
21925#endif
21926 const_reference lhs = *this;
21927 JSON_IMPLEMENT_OPERATOR(== , true, false, false)
21928#ifdef __GNUC__
21929#pragma GCC diagnostic pop
21930#endif
21931 }
21932
21935 template<typename ScalarType>
21936 requires std::is_scalar_v<ScalarType>
21937 bool operator==(ScalarType rhs) const noexcept
21938 {
21939 return *this == basic_json(rhs);
21940 }
21941
21944 bool operator!=(const_reference rhs) const noexcept
21945 {
21946 if (compares_unordered(rhs, true))
21947 {
21948 return false;
21949 }
21950 return !operator==(rhs);
21951 }
21952
21955 std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
21956 {
21957 const_reference lhs = *this;
21958 // default_result is used if we cannot compare values. In that case,
21959 // we compare types.
21960 JSON_IMPLEMENT_OPERATOR(<=> , // *NOPAD*
21961 std::partial_ordering::equivalent,
21962 std::partial_ordering::unordered,
21963 lhs_type <=> rhs_type) // *NOPAD*
21964 }
21965
21968 template<typename ScalarType>
21969 requires std::is_scalar_v<ScalarType>
21970 std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
21971 {
21972 return *this <=> basic_json(rhs); // *NOPAD*
21973 }
21974
21975#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
21976 // all operators that are computed as an odd number of inverses of others
21977 // need to be overloaded to emulate the legacy comparison behavior
21978
21982 bool operator<=(const_reference rhs) const noexcept
21983 {
21984 if (compares_unordered(rhs, true))
21985 {
21986 return false;
21987 }
21988 return !(rhs < *this);
21989 }
21990
21993 template<typename ScalarType>
21994 requires std::is_scalar_v<ScalarType>
21995 bool operator<=(ScalarType rhs) const noexcept
21996 {
21997 return *this <= basic_json(rhs);
21998 }
21999
22003 bool operator>=(const_reference rhs) const noexcept
22004 {
22005 if (compares_unordered(rhs, true))
22006 {
22007 return false;
22008 }
22009 return !(*this < rhs);
22010 }
22011
22014 template<typename ScalarType>
22015 requires std::is_scalar_v<ScalarType>
22016 bool operator>=(ScalarType rhs) const noexcept
22017 {
22018 return *this >= basic_json(rhs);
22019 }
22020#endif
22021#else
22024 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22025 {
22026#ifdef __GNUC__
22027#pragma GCC diagnostic push
22028#pragma GCC diagnostic ignored "-Wfloat-equal"
22029#endif
22030 JSON_IMPLEMENT_OPERATOR(== , true, false, false)
22031#ifdef __GNUC__
22032#pragma GCC diagnostic pop
22033#endif
22034 }
22035
22038 template<typename ScalarType, typename std::enable_if<
22039 std::is_scalar<ScalarType>::value, int>::type = 0>
22040 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
22041 {
22042 return lhs == basic_json(rhs);
22043 }
22044
22047 template<typename ScalarType, typename std::enable_if<
22048 std::is_scalar<ScalarType>::value, int>::type = 0>
22049 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
22050 {
22051 return basic_json(lhs) == rhs;
22052 }
22053
22056 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22057 {
22058 if (compares_unordered(lhs, rhs, true))
22059 {
22060 return false;
22061 }
22062 return !(lhs == rhs);
22063 }
22064
22067 template<typename ScalarType, typename std::enable_if<
22068 std::is_scalar<ScalarType>::value, int>::type = 0>
22069 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
22070 {
22071 return lhs != basic_json(rhs);
22072 }
22073
22076 template<typename ScalarType, typename std::enable_if<
22077 std::is_scalar<ScalarType>::value, int>::type = 0>
22078 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
22079 {
22080 return basic_json(lhs) != rhs;
22081 }
22082
22085 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22086 {
22087 // default_result is used if we cannot compare values. In that case,
22088 // we compare types. Note we have to call the operator explicitly,
22089 // because MSVC has problems otherwise.
22090 JSON_IMPLEMENT_OPERATOR(< , false, false, operator<(lhs_type, rhs_type))
22091 }
22092
22095 template<typename ScalarType, typename std::enable_if<
22096 std::is_scalar<ScalarType>::value, int>::type = 0>
22097 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
22098 {
22099 return lhs < basic_json(rhs);
22100 }
22101
22104 template<typename ScalarType, typename std::enable_if<
22105 std::is_scalar<ScalarType>::value, int>::type = 0>
22106 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
22107 {
22108 return basic_json(lhs) < rhs;
22109 }
22110
22113 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22114 {
22115 if (compares_unordered(lhs, rhs, true))
22116 {
22117 return false;
22118 }
22119 return !(rhs < lhs);
22120 }
22121
22124 template<typename ScalarType, typename std::enable_if<
22125 std::is_scalar<ScalarType>::value, int>::type = 0>
22126 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
22127 {
22128 return lhs <= basic_json(rhs);
22129 }
22130
22133 template<typename ScalarType, typename std::enable_if<
22134 std::is_scalar<ScalarType>::value, int>::type = 0>
22135 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
22136 {
22137 return basic_json(lhs) <= rhs;
22138 }
22139
22142 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22143 {
22144 // double inverse
22145 if (compares_unordered(lhs, rhs))
22146 {
22147 return false;
22148 }
22149 return !(lhs <= rhs);
22150 }
22151
22154 template<typename ScalarType, typename std::enable_if<
22155 std::is_scalar<ScalarType>::value, int>::type = 0>
22156 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
22157 {
22158 return lhs > basic_json(rhs);
22159 }
22160
22163 template<typename ScalarType, typename std::enable_if<
22164 std::is_scalar<ScalarType>::value, int>::type = 0>
22165 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
22166 {
22167 return basic_json(lhs) > rhs;
22168 }
22169
22172 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22173 {
22174 if (compares_unordered(lhs, rhs, true))
22175 {
22176 return false;
22177 }
22178 return !(lhs < rhs);
22179 }
22180
22183 template<typename ScalarType, typename std::enable_if<
22184 std::is_scalar<ScalarType>::value, int>::type = 0>
22185 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
22186 {
22187 return lhs >= basic_json(rhs);
22188 }
22189
22192 template<typename ScalarType, typename std::enable_if<
22193 std::is_scalar<ScalarType>::value, int>::type = 0>
22194 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
22195 {
22196 return basic_json(lhs) >= rhs;
22197 }
22198#endif
22199
22200#undef JSON_IMPLEMENT_OPERATOR
22201
22203
22205 // serialization //
22207
22210#ifndef JSON_NO_IO
22213 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22214 {
22215 // read width member and use it as indentation parameter if nonzero
22216 const bool pretty_print = o.width() > 0;
22217 const auto indentation = pretty_print ? o.width() : 0;
22218
22219 // reset width to 0 for subsequent calls to this stream
22220 o.width(0);
22221
22222 // do the actual serialization
22223 serializer s(detail::output_adapter<char>(o), o.fill());
22224 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22225 return o;
22226 }
22227
22234 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
22235 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22236 {
22237 return o << j;
22238 }
22239#endif // JSON_NO_IO
22241
22242
22244 // deserialization //
22246
22249
22252 template<typename InputType>
22254 static basic_json parse(InputType&& i,
22255 const parser_callback_t cb = nullptr,
22256 const bool allow_exceptions = true,
22257 const bool ignore_comments = false)
22258 {
22259 basic_json result;
22260 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
22261 return result;
22262 }
22263
22266 template<typename IteratorType>
22268 static basic_json parse(IteratorType first,
22269 IteratorType last,
22270 const parser_callback_t cb = nullptr,
22271 const bool allow_exceptions = true,
22272 const bool ignore_comments = false)
22273 {
22274 basic_json result;
22275 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
22276 return result;
22277 }
22278
22280 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
22281 static basic_json parse(detail::span_input_adapter&& i,
22282 const parser_callback_t cb = nullptr,
22283 const bool allow_exceptions = true,
22284 const bool ignore_comments = false)
22285 {
22286 basic_json result;
22287 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
22288 return result;
22289 }
22290
22293 template<typename InputType>
22294 static bool accept(InputType&& i,
22295 const bool ignore_comments = false)
22296 {
22297 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
22298 }
22299
22302 template<typename IteratorType>
22303 static bool accept(IteratorType first, IteratorType last,
22304 const bool ignore_comments = false)
22305 {
22306 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
22307 }
22308
22310 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
22311 static bool accept(detail::span_input_adapter&& i,
22312 const bool ignore_comments = false)
22313 {
22314 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
22315 }
22316
22319 template <typename InputType, typename SAX>
22321 static bool sax_parse(InputType&& i, SAX* sax,
22323 const bool strict = true,
22324 const bool ignore_comments = false)
22325 {
22326 auto ia = detail::input_adapter(std::forward<InputType>(i));
22327 return format == input_format_t::json
22328 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22329 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22330 }
22331
22334 template<class IteratorType, class SAX>
22336 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
22338 const bool strict = true,
22339 const bool ignore_comments = false)
22340 {
22341 auto ia = detail::input_adapter(std::move(first), std::move(last));
22342 return format == input_format_t::json
22343 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22344 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22345 }
22346
22352 template <typename SAX>
22353 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
22355 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22357 const bool strict = true,
22358 const bool ignore_comments = false)
22359 {
22360 auto ia = i.get();
22361 return format == input_format_t::json
22362 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22363 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22364 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22365 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22366 }
22367#ifndef JSON_NO_IO
22374 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
22375 friend std::istream& operator<<(basic_json& j, std::istream& i)
22376 {
22377 return operator>>(i, j);
22378 }
22379
22382 friend std::istream& operator>>(std::istream& i, basic_json& j)
22383 {
22384 parser(detail::input_adapter(i)).parse(false, j);
22385 return i;
22386 }
22387#endif // JSON_NO_IO
22389
22391 // convenience functions //
22393
22397 const char* type_name() const noexcept
22398 {
22399 switch (m_type)
22400 {
22401 case value_t::null:
22402 return "null";
22403 case value_t::object:
22404 return "object";
22405 case value_t::array:
22406 return "array";
22407 case value_t::string:
22408 return "string";
22409 case value_t::boolean:
22410 return "boolean";
22411 case value_t::binary:
22412 return "binary";
22413 case value_t::discarded:
22414 return "discarded";
22418 default:
22419 return "number";
22420 }
22421 }
22422
22423
22426 // member variables //
22428
22430 value_t m_type = value_t::null;
22431
22433 json_value m_value = {};
22434
22435#if JSON_DIAGNOSTICS
22437 basic_json* m_parent = nullptr;
22438#endif
22439
22441 // binary serialization/deserialization //
22443
22446
22447 public:
22450 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
22451 {
22452 std::vector<std::uint8_t> result;
22453 to_cbor(j, result);
22454 return result;
22455 }
22456
22460 {
22462 }
22463
22467 {
22469 }
22470
22473 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
22474 {
22475 std::vector<std::uint8_t> result;
22476 to_msgpack(j, result);
22477 return result;
22478 }
22479
22483 {
22485 }
22486
22490 {
22492 }
22493
22496 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
22497 const bool use_size = false,
22498 const bool use_type = false)
22499 {
22500 std::vector<std::uint8_t> result;
22501 to_ubjson(j, result, use_size, use_type);
22502 return result;
22503 }
22504
22508 const bool use_size = false, const bool use_type = false)
22509 {
22510 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
22511 }
22512
22516 const bool use_size = false, const bool use_type = false)
22517 {
22518 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
22519 }
22520
22523 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
22524 const bool use_size = false,
22525 const bool use_type = false)
22526 {
22527 std::vector<std::uint8_t> result;
22528 to_bjdata(j, result, use_size, use_type);
22529 return result;
22530 }
22531
22535 const bool use_size = false, const bool use_type = false)
22536 {
22537 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
22538 }
22539
22543 const bool use_size = false, const bool use_type = false)
22544 {
22545 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
22546 }
22547
22550 static std::vector<std::uint8_t> to_bson(const basic_json& j)
22551 {
22552 std::vector<std::uint8_t> result;
22553 to_bson(j, result);
22554 return result;
22555 }
22556
22560 {
22562 }
22563
22567 {
22569 }
22570
22573 template<typename InputType>
22575 static basic_json from_cbor(InputType&& i,
22576 const bool strict = true,
22577 const bool allow_exceptions = true,
22578 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22579 {
22580 basic_json result;
22581 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22582 auto ia = detail::input_adapter(std::forward<InputType>(i));
22583 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22584 return res ? result : basic_json(value_t::discarded);
22585 }
22586
22589 template<typename IteratorType>
22591 static basic_json from_cbor(IteratorType first, IteratorType last,
22592 const bool strict = true,
22593 const bool allow_exceptions = true,
22594 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22595 {
22596 basic_json result;
22597 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22598 auto ia = detail::input_adapter(std::move(first), std::move(last));
22599 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22600 return res ? result : basic_json(value_t::discarded);
22601 }
22602
22603 template<typename T>
22605 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22606 static basic_json from_cbor(const T* ptr, std::size_t len,
22607 const bool strict = true,
22608 const bool allow_exceptions = true,
22609 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22610 {
22611 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
22612 }
22613
22614
22616 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22617 static basic_json from_cbor(detail::span_input_adapter&& i,
22618 const bool strict = true,
22619 const bool allow_exceptions = true,
22620 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22621 {
22622 basic_json result;
22623 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22624 auto ia = i.get();
22625 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22626 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22627 return res ? result : basic_json(value_t::discarded);
22628 }
22629
22632 template<typename InputType>
22634 static basic_json from_msgpack(InputType&& i,
22635 const bool strict = true,
22636 const bool allow_exceptions = true)
22637 {
22638 basic_json result;
22639 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22640 auto ia = detail::input_adapter(std::forward<InputType>(i));
22641 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22642 return res ? result : basic_json(value_t::discarded);
22643 }
22644
22647 template<typename IteratorType>
22649 static basic_json from_msgpack(IteratorType first, IteratorType last,
22650 const bool strict = true,
22651 const bool allow_exceptions = true)
22652 {
22653 basic_json result;
22654 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22655 auto ia = detail::input_adapter(std::move(first), std::move(last));
22656 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22657 return res ? result : basic_json(value_t::discarded);
22658 }
22659
22660 template<typename T>
22662 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22663 static basic_json from_msgpack(const T* ptr, std::size_t len,
22664 const bool strict = true,
22665 const bool allow_exceptions = true)
22666 {
22667 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
22668 }
22669
22671 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22672 static basic_json from_msgpack(detail::span_input_adapter&& i,
22673 const bool strict = true,
22674 const bool allow_exceptions = true)
22675 {
22676 basic_json result;
22677 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22678 auto ia = i.get();
22679 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22680 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22681 return res ? result : basic_json(value_t::discarded);
22682 }
22683
22686 template<typename InputType>
22688 static basic_json from_ubjson(InputType&& i,
22689 const bool strict = true,
22690 const bool allow_exceptions = true)
22691 {
22692 basic_json result;
22693 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22694 auto ia = detail::input_adapter(std::forward<InputType>(i));
22695 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22696 return res ? result : basic_json(value_t::discarded);
22697 }
22698
22701 template<typename IteratorType>
22703 static basic_json from_ubjson(IteratorType first, IteratorType last,
22704 const bool strict = true,
22705 const bool allow_exceptions = true)
22706 {
22707 basic_json result;
22708 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22709 auto ia = detail::input_adapter(std::move(first), std::move(last));
22710 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22711 return res ? result : basic_json(value_t::discarded);
22712 }
22713
22714 template<typename T>
22716 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22717 static basic_json from_ubjson(const T* ptr, std::size_t len,
22718 const bool strict = true,
22719 const bool allow_exceptions = true)
22720 {
22721 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
22722 }
22723
22725 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22726 static basic_json from_ubjson(detail::span_input_adapter&& i,
22727 const bool strict = true,
22728 const bool allow_exceptions = true)
22729 {
22730 basic_json result;
22731 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22732 auto ia = i.get();
22733 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22734 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22735 return res ? result : basic_json(value_t::discarded);
22736 }
22737
22738
22741 template<typename InputType>
22743 static basic_json from_bjdata(InputType&& i,
22744 const bool strict = true,
22745 const bool allow_exceptions = true)
22746 {
22747 basic_json result;
22748 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22749 auto ia = detail::input_adapter(std::forward<InputType>(i));
22750 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22751 return res ? result : basic_json(value_t::discarded);
22752 }
22753
22756 template<typename IteratorType>
22758 static basic_json from_bjdata(IteratorType first, IteratorType last,
22759 const bool strict = true,
22760 const bool allow_exceptions = true)
22761 {
22762 basic_json result;
22763 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22764 auto ia = detail::input_adapter(std::move(first), std::move(last));
22765 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
22766 return res ? result : basic_json(value_t::discarded);
22767 }
22768
22771 template<typename InputType>
22773 static basic_json from_bson(InputType&& i,
22774 const bool strict = true,
22775 const bool allow_exceptions = true)
22776 {
22777 basic_json result;
22778 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22779 auto ia = detail::input_adapter(std::forward<InputType>(i));
22780 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22781 return res ? result : basic_json(value_t::discarded);
22782 }
22783
22786 template<typename IteratorType>
22788 static basic_json from_bson(IteratorType first, IteratorType last,
22789 const bool strict = true,
22790 const bool allow_exceptions = true)
22791 {
22792 basic_json result;
22793 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22794 auto ia = detail::input_adapter(std::move(first), std::move(last));
22795 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22796 return res ? result : basic_json(value_t::discarded);
22797 }
22798
22799 template<typename T>
22801 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
22802 static basic_json from_bson(const T* ptr, std::size_t len,
22803 const bool strict = true,
22804 const bool allow_exceptions = true)
22805 {
22806 return from_bson(ptr, ptr + len, strict, allow_exceptions);
22807 }
22808
22810 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
22811 static basic_json from_bson(detail::span_input_adapter&& i,
22812 const bool strict = true,
22813 const bool allow_exceptions = true)
22814 {
22815 basic_json result;
22816 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22817 auto ia = i.get();
22818 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22819 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
22820 return res ? result : basic_json(value_t::discarded);
22821 }
22823
22825 // JSON Pointer support //
22827
22830
22834 {
22835 return ptr.get_unchecked(this);
22836 }
22837
22838 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22840 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
22841 {
22842 return ptr.get_unchecked(this);
22843 }
22844
22848 {
22849 return ptr.get_unchecked(this);
22850 }
22851
22852 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22854 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22855 {
22856 return ptr.get_unchecked(this);
22857 }
22858
22861 reference at(const json_pointer& ptr)
22862 {
22863 return ptr.get_checked(this);
22864 }
22865
22866 template<typename BasicJsonType>
22868 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
22869 {
22870 return ptr.get_checked(this);
22871 }
22872
22876 {
22877 return ptr.get_checked(this);
22878 }
22879
22880 template<typename BasicJsonType>
22882 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22883 {
22884 return ptr.get_checked(this);
22885 }
22886
22889 basic_json flatten() const
22890 {
22892 json_pointer::flatten("", *this, result);
22893 return result;
22894 }
22895
22898 basic_json unflatten() const
22899 {
22900 return json_pointer::unflatten(*this);
22901 }
22902
22904
22906 // JSON Patch functions //
22908
22911
22914 basic_json patch(const basic_json& json_patch) const
22915 {
22916 // make a working copy to apply the patch to
22917 basic_json result = *this;
22918
22919 // the valid JSON Patch operations
22920 enum class patch_operations { add, remove, replace, move, copy, test, invalid };
22921
22922 const auto get_op = [](const std::string& op)
22923 {
22924 if (op == "add")
22925 {
22926 return patch_operations::add;
22927 }
22928 if (op == "remove")
22929 {
22930 return patch_operations::remove;
22931 }
22932 if (op == "replace")
22933 {
22934 return patch_operations::replace;
22935 }
22936 if (op == "move")
22937 {
22938 return patch_operations::move;
22939 }
22940 if (op == "copy")
22941 {
22942 return patch_operations::copy;
22943 }
22944 if (op == "test")
22945 {
22946 return patch_operations::test;
22947 }
22948
22949 return patch_operations::invalid;
22950 };
22951
22952 // wrapper for "add" operation; add value at ptr
22953 const auto operation_add = [&result](json_pointer& ptr, basic_json val)
22954 {
22955 // adding to the root of the target document means replacing it
22956 if (ptr.empty())
22957 {
22958 result = val;
22959 return;
22960 }
22961
22962 // make sure the top element of the pointer exists
22963 json_pointer top_pointer = ptr.top();
22964 if (top_pointer != ptr)
22965 {
22966 result.at(top_pointer);
22967 }
22968
22969 // get reference to parent of JSON pointer ptr
22970 const auto last_path = ptr.back();
22971 ptr.pop_back();
22972 basic_json& parent = result[ptr];
22973
22974 switch (parent.m_type)
22975 {
22976 case value_t::null:
22977 case value_t::object:
22978 {
22979 // use operator[] to add value
22980 parent[last_path] = val;
22981 break;
22982 }
22983
22984 case value_t::array:
22985 {
22986 if (last_path == "-")
22987 {
22988 // special case: append to back
22989 parent.push_back(val);
22990 }
22991 else
22992 {
22993 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
22994 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
22995 {
22996 // avoid undefined behavior
22997 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
22998 }
22999
23000 // default case: insert add offset
23001 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23002 }
23003 break;
23004 }
23005
23006 // if there exists a parent it cannot be primitive
23007 case value_t::string: // LCOV_EXCL_LINE
23008 case value_t::boolean: // LCOV_EXCL_LINE
23009 case value_t::number_integer: // LCOV_EXCL_LINE
23010 case value_t::number_unsigned: // LCOV_EXCL_LINE
23011 case value_t::number_float: // LCOV_EXCL_LINE
23012 case value_t::binary: // LCOV_EXCL_LINE
23013 case value_t::discarded: // LCOV_EXCL_LINE
23014 default: // LCOV_EXCL_LINE
23015 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
23016 }
23017 };
23018
23019 // wrapper for "remove" operation; remove value at ptr
23020 const auto operation_remove = [this, &result](json_pointer& ptr)
23021 {
23022 // get reference to parent of JSON pointer ptr
23023 const auto last_path = ptr.back();
23024 ptr.pop_back();
23025 basic_json& parent = result.at(ptr);
23026
23027 // remove child
23028 if (parent.is_object())
23029 {
23030 // perform range check
23031 auto it = parent.find(last_path);
23032 if (JSON_HEDLEY_LIKELY(it != parent.end()))
23033 {
23034 parent.erase(it);
23035 }
23036 else
23037 {
23038 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
23039 }
23040 }
23041 else if (parent.is_array())
23042 {
23043 // note erase performs range check
23044 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
23045 }
23046 };
23047
23048 // type check: top level value must be an array
23049 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
23050 {
23051 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
23052 }
23053
23054 // iterate and apply the operations
23055 for (const auto& val : json_patch)
23056 {
23057 // wrapper to get a value for an operation
23058 const auto get_value = [&val](const std::string& op,
23059 const std::string& member,
23060 bool string_type) -> basic_json&
23061 {
23062 // find value
23063 auto it = val.m_value.object->find(member);
23064
23065 // context-sensitive error message
23066 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
23067
23068 // check if desired value is present
23069 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
23070 {
23071 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
23072 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
23073 }
23074
23075 // check if result is of type string
23076 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
23077 {
23078 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
23079 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
23080 }
23081
23082 // no error: return value
23083 return it->second;
23084 };
23085
23086 // type check: every element of the array must be an object
23087 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
23088 {
23089 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
23090 }
23091
23092 // collect mandatory members
23093 const auto op = get_value("op", "op", true).template get<std::string>();
23094 const auto path = get_value(op, "path", true).template get<std::string>();
23095 json_pointer ptr(path);
23096
23097 switch (get_op(op))
23098 {
23099 case patch_operations::add:
23100 {
23101 operation_add(ptr, get_value("add", "value", false));
23102 break;
23103 }
23104
23105 case patch_operations::remove:
23106 {
23107 operation_remove(ptr);
23108 break;
23109 }
23110
23111 case patch_operations::replace:
23112 {
23113 // the "path" location must exist - use at()
23114 result.at(ptr) = get_value("replace", "value", false);
23115 break;
23116 }
23117
23118 case patch_operations::move:
23119 {
23120 const auto from_path = get_value("move", "from", true).template get<std::string>();
23121 json_pointer from_ptr(from_path);
23122
23123 // the "from" location must exist - use at()
23124 basic_json v = result.at(from_ptr);
23125
23126 // The move operation is functionally identical to a
23127 // "remove" operation on the "from" location, followed
23128 // immediately by an "add" operation at the target
23129 // location with the value that was just removed.
23130 operation_remove(from_ptr);
23131 operation_add(ptr, v);
23132 break;
23133 }
23134
23135 case patch_operations::copy:
23136 {
23137 const auto from_path = get_value("copy", "from", true).template get<std::string>();
23138 const json_pointer from_ptr(from_path);
23139
23140 // the "from" location must exist - use at()
23141 basic_json v = result.at(from_ptr);
23142
23143 // The copy is functionally identical to an "add"
23144 // operation at the target location using the value
23145 // specified in the "from" member.
23146 operation_add(ptr, v);
23147 break;
23148 }
23149
23150 case patch_operations::test:
23151 {
23152 bool success = false;
23153 JSON_TRY
23154 {
23155 // check if "value" matches the one at "path"
23156 // the "path" location must exist - use at()
23157 success = (result.at(ptr) == get_value("test", "value", false));
23158 }
23160 {
23161 // ignore out of range errors: success remains false
23162 }
23163
23164 // throw an exception if test fails
23165 if (JSON_HEDLEY_UNLIKELY(!success))
23166 {
23167 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
23168 }
23169
23170 break;
23171 }
23172
23173 case patch_operations::invalid:
23174 default:
23175 {
23176 // op must be "add", "remove", "replace", "move", "copy", or
23177 // "test"
23178 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
23179 }
23180 }
23181 }
23182
23183 return result;
23184 }
23185
23189 static basic_json diff(const basic_json& source, const basic_json& target,
23190 const std::string& path = "")
23191 {
23192 // the patch
23193 basic_json result(value_t::array);
23194
23195 // if the values are the same, return empty patch
23196 if (source == target)
23197 {
23198 return result;
23199 }
23200
23201 if (source.type() != target.type())
23202 {
23203 // different types: replace value
23204 result.push_back(
23205 {
23206 {"op", "replace"}, {"path", path}, {"value", target}
23207 });
23208 return result;
23209 }
23210
23211 switch (source.type())
23212 {
23213 case value_t::array:
23214 {
23215 // first pass: traverse common elements
23216 std::size_t i = 0;
23217 while (i < source.size() && i < target.size())
23218 {
23219 // recursive call to compare array values at index i
23220 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
23221 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23222 ++i;
23223 }
23224
23225 // We now reached the end of at least one array
23226 // in a second pass, traverse the remaining elements
23227
23228 // remove my remaining elements
23229 const auto end_index = static_cast<difference_type>(result.size());
23230 while (i < source.size())
23231 {
23232 // add operations in reverse order to avoid invalid
23233 // indices
23234 result.insert(result.begin() + end_index, object(
23235 {
23236 {"op", "remove"},
23237 {"path", detail::concat(path, '/', std::to_string(i))}
23238 }));
23239 ++i;
23240 }
23241
23242 // add other remaining elements
23243 while (i < target.size())
23244 {
23245 result.push_back(
23246 {
23247 {"op", "add"},
23248 {"path", detail::concat(path, "/-")},
23249 {"value", target[i]}
23250 });
23251 ++i;
23252 }
23253
23254 break;
23255 }
23256
23257 case value_t::object:
23258 {
23259 // first pass: traverse this object's elements
23260 for (auto it = source.cbegin(); it != source.cend(); ++it)
23261 {
23262 // escape the key name to be used in a JSON patch
23263 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23264
23265 if (target.find(it.key()) != target.end())
23266 {
23267 // recursive call to compare object values at key it
23268 auto temp_diff = diff(it.value(), target[it.key()], path_key);
23269 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23270 }
23271 else
23272 {
23273 // found a key that is not in o -> remove it
23274 result.push_back(object(
23275 {
23276 {"op", "remove"}, {"path", path_key}
23277 }));
23278 }
23279 }
23280
23281 // second pass: traverse other object's elements
23282 for (auto it = target.cbegin(); it != target.cend(); ++it)
23283 {
23284 if (source.find(it.key()) == source.end())
23285 {
23286 // found a key that is not in this -> add it
23287 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23288 result.push_back(
23289 {
23290 {"op", "add"}, {"path", path_key},
23291 {"value", it.value()}
23292 });
23293 }
23294 }
23295
23296 break;
23297 }
23298
23299 case value_t::null:
23300 case value_t::string:
23301 case value_t::boolean:
23305 case value_t::binary:
23306 case value_t::discarded:
23307 default:
23308 {
23309 // both primitive type: replace value
23310 result.push_back(
23311 {
23312 {"op", "replace"}, {"path", path}, {"value", target}
23313 });
23314 break;
23315 }
23316 }
23317
23318 return result;
23319 }
23320
23322
23324 // JSON Merge Patch functions //
23326
23329
23332 void merge_patch(const basic_json& apply_patch)
23333 {
23334 if (apply_patch.is_object())
23335 {
23336 if (!is_object())
23337 {
23338 *this = object();
23339 }
23340 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
23341 {
23342 if (it.value().is_null())
23343 {
23344 erase(it.key());
23345 }
23346 else
23347 {
23348 operator[](it.key()).merge_patch(it.value());
23349 }
23350 }
23351 }
23352 else
23353 {
23354 *this = apply_patch;
23355 }
23356 }
23357
23359 };
23360
23365 {
23366 return j.dump();
23367 }
23368
23369} // namespace nlohmann
23370
23372// nonmember support //
23374
23375namespace std // NOLINT(cert-dcl58-cpp)
23376{
23377
23382 {
23384 {
23385 return nlohmann::detail::hash(j);
23386 }
23387 };
23388
23389 // specialization for std::less<value_t>
23390 template<>
23391 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
23392 {
23398 ::nlohmann::detail::value_t rhs) const noexcept
23399 {
23400#if JSON_HAS_THREE_WAY_COMPARISON
23401 return std::is_lt(lhs <=> rhs); // *NOPAD*
23402#else
23404#endif
23405 }
23406 };
23407
23408 // C++20 prohibit function specialization in the std namespace.
23409#ifndef JSON_HAS_CPP_20
23410
23414 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
23415 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
23416 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
23417 {
23418 j1.swap(j2);
23419 }
23420
23421#endif
23422
23423} // namespace std
23424
23428inline nlohmann::json operator "" _json(const char* s, std::size_t n)
23429{
23430 return nlohmann::json::parse(s, s + n);
23431}
23432
23436inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
23437{
23438 return nlohmann::json::json_pointer(std::string(s, n));
23439}
23440
23441// #include <nlohmann/detail/macro_unscope.hpp>
23442
23443
23444// restore clang diagnostic settings
23445#if defined(__clang__)
23446#pragma clang diagnostic pop
23447#endif
23448
23449// clean up
23450#undef JSON_ASSERT
23451#undef JSON_INTERNAL_CATCH
23452#undef JSON_THROW
23453#undef JSON_PRIVATE_UNLESS_TESTED
23454#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
23455#undef NLOHMANN_BASIC_JSON_TPL
23456#undef JSON_EXPLICIT
23457#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
23458#undef JSON_INLINE_VARIABLE
23459#undef JSON_NO_UNIQUE_ADDRESS
23460
23461#ifndef JSON_TEST_KEEP_MACROS
23462#undef JSON_CATCH
23463#undef JSON_TRY
23464#undef JSON_HAS_CPP_11
23465#undef JSON_HAS_CPP_14
23466#undef JSON_HAS_CPP_17
23467#undef JSON_HAS_CPP_20
23468#undef JSON_HAS_FILESYSTEM
23469#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
23470#undef JSON_HAS_THREE_WAY_COMPARISON
23471#undef JSON_HAS_RANGES
23472#undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23473#endif
23474
23475// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
23476
23477
23478#undef JSON_HEDLEY_ALWAYS_INLINE
23479#undef JSON_HEDLEY_ARM_VERSION
23480#undef JSON_HEDLEY_ARM_VERSION_CHECK
23481#undef JSON_HEDLEY_ARRAY_PARAM
23482#undef JSON_HEDLEY_ASSUME
23483#undef JSON_HEDLEY_BEGIN_C_DECLS
23484#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
23485#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
23486#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
23487#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
23488#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
23489#undef JSON_HEDLEY_CLANG_HAS_FEATURE
23490#undef JSON_HEDLEY_CLANG_HAS_WARNING
23491#undef JSON_HEDLEY_COMPCERT_VERSION
23492#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
23493#undef JSON_HEDLEY_CONCAT
23494#undef JSON_HEDLEY_CONCAT3
23495#undef JSON_HEDLEY_CONCAT3_EX
23496#undef JSON_HEDLEY_CONCAT_EX
23497#undef JSON_HEDLEY_CONST
23498#undef JSON_HEDLEY_CONSTEXPR
23499#undef JSON_HEDLEY_CONST_CAST
23500#undef JSON_HEDLEY_CPP_CAST
23501#undef JSON_HEDLEY_CRAY_VERSION
23502#undef JSON_HEDLEY_CRAY_VERSION_CHECK
23503#undef JSON_HEDLEY_C_DECL
23504#undef JSON_HEDLEY_DEPRECATED
23505#undef JSON_HEDLEY_DEPRECATED_FOR
23506#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
23507#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
23508#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
23509#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
23510#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
23511#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
23512#undef JSON_HEDLEY_DIAGNOSTIC_POP
23513#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
23514#undef JSON_HEDLEY_DMC_VERSION
23515#undef JSON_HEDLEY_DMC_VERSION_CHECK
23516#undef JSON_HEDLEY_EMPTY_BASES
23517#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
23518#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
23519#undef JSON_HEDLEY_END_C_DECLS
23520#undef JSON_HEDLEY_FLAGS
23521#undef JSON_HEDLEY_FLAGS_CAST
23522#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
23523#undef JSON_HEDLEY_GCC_HAS_BUILTIN
23524#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
23525#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
23526#undef JSON_HEDLEY_GCC_HAS_EXTENSION
23527#undef JSON_HEDLEY_GCC_HAS_FEATURE
23528#undef JSON_HEDLEY_GCC_HAS_WARNING
23529#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
23530#undef JSON_HEDLEY_GCC_VERSION
23531#undef JSON_HEDLEY_GCC_VERSION_CHECK
23532#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
23533#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
23534#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
23535#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
23536#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
23537#undef JSON_HEDLEY_GNUC_HAS_FEATURE
23538#undef JSON_HEDLEY_GNUC_HAS_WARNING
23539#undef JSON_HEDLEY_GNUC_VERSION
23540#undef JSON_HEDLEY_GNUC_VERSION_CHECK
23541#undef JSON_HEDLEY_HAS_ATTRIBUTE
23542#undef JSON_HEDLEY_HAS_BUILTIN
23543#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
23544#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
23545#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
23546#undef JSON_HEDLEY_HAS_EXTENSION
23547#undef JSON_HEDLEY_HAS_FEATURE
23548#undef JSON_HEDLEY_HAS_WARNING
23549#undef JSON_HEDLEY_IAR_VERSION
23550#undef JSON_HEDLEY_IAR_VERSION_CHECK
23551#undef JSON_HEDLEY_IBM_VERSION
23552#undef JSON_HEDLEY_IBM_VERSION_CHECK
23553#undef JSON_HEDLEY_IMPORT
23554#undef JSON_HEDLEY_INLINE
23555#undef JSON_HEDLEY_INTEL_CL_VERSION
23556#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
23557#undef JSON_HEDLEY_INTEL_VERSION
23558#undef JSON_HEDLEY_INTEL_VERSION_CHECK
23559#undef JSON_HEDLEY_IS_CONSTANT
23560#undef JSON_HEDLEY_IS_CONSTEXPR_
23561#undef JSON_HEDLEY_LIKELY
23562#undef JSON_HEDLEY_MALLOC
23563#undef JSON_HEDLEY_MCST_LCC_VERSION
23564#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
23565#undef JSON_HEDLEY_MESSAGE
23566#undef JSON_HEDLEY_MSVC_VERSION
23567#undef JSON_HEDLEY_MSVC_VERSION_CHECK
23568#undef JSON_HEDLEY_NEVER_INLINE
23569#undef JSON_HEDLEY_NON_NULL
23570#undef JSON_HEDLEY_NO_ESCAPE
23571#undef JSON_HEDLEY_NO_RETURN
23572#undef JSON_HEDLEY_NO_THROW
23573#undef JSON_HEDLEY_NULL
23574#undef JSON_HEDLEY_PELLES_VERSION
23575#undef JSON_HEDLEY_PELLES_VERSION_CHECK
23576#undef JSON_HEDLEY_PGI_VERSION
23577#undef JSON_HEDLEY_PGI_VERSION_CHECK
23578#undef JSON_HEDLEY_PREDICT
23579#undef JSON_HEDLEY_PRINTF_FORMAT
23580#undef JSON_HEDLEY_PRIVATE
23581#undef JSON_HEDLEY_PUBLIC
23582#undef JSON_HEDLEY_PURE
23583#undef JSON_HEDLEY_REINTERPRET_CAST
23584#undef JSON_HEDLEY_REQUIRE
23585#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
23586#undef JSON_HEDLEY_REQUIRE_MSG
23587#undef JSON_HEDLEY_RESTRICT
23588#undef JSON_HEDLEY_RETURNS_NON_NULL
23589#undef JSON_HEDLEY_SENTINEL
23590#undef JSON_HEDLEY_STATIC_ASSERT
23591#undef JSON_HEDLEY_STATIC_CAST
23592#undef JSON_HEDLEY_STRINGIFY
23593#undef JSON_HEDLEY_STRINGIFY_EX
23594#undef JSON_HEDLEY_SUNPRO_VERSION
23595#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
23596#undef JSON_HEDLEY_TINYC_VERSION
23597#undef JSON_HEDLEY_TINYC_VERSION_CHECK
23598#undef JSON_HEDLEY_TI_ARMCL_VERSION
23599#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
23600#undef JSON_HEDLEY_TI_CL2000_VERSION
23601#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
23602#undef JSON_HEDLEY_TI_CL430_VERSION
23603#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
23604#undef JSON_HEDLEY_TI_CL6X_VERSION
23605#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
23606#undef JSON_HEDLEY_TI_CL7X_VERSION
23607#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
23608#undef JSON_HEDLEY_TI_CLPRU_VERSION
23609#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
23610#undef JSON_HEDLEY_TI_VERSION
23611#undef JSON_HEDLEY_TI_VERSION_CHECK
23612#undef JSON_HEDLEY_UNAVAILABLE
23613#undef JSON_HEDLEY_UNLIKELY
23614#undef JSON_HEDLEY_UNPREDICTABLE
23615#undef JSON_HEDLEY_UNREACHABLE
23616#undef JSON_HEDLEY_UNREACHABLE_RETURN
23617#undef JSON_HEDLEY_VERSION
23618#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
23619#undef JSON_HEDLEY_VERSION_DECODE_MINOR
23620#undef JSON_HEDLEY_VERSION_DECODE_REVISION
23621#undef JSON_HEDLEY_VERSION_ENCODE
23622#undef JSON_HEDLEY_WARNING
23623#undef JSON_HEDLEY_WARN_UNUSED_RESULT
23624#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
23625#undef JSON_HEDLEY_FALL_THROUGH
23626
23627
23628
23629#endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::json json
Definition: GameObjectFactory.cpp:10
a class to store JSON values
Definition: json.hpp:18399
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20100
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:21626
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:19095
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:22847
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:22833
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:19639
const_reference operator[](T *key) const
Definition: json.hpp:20453
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:18656
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:21651
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:22523
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:18465
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20123
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21452
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:19108
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:20921
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:22550
value_type & reference
the type of an element reference
Definition: json.hpp:18510
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:20861
detail::out_of_range out_of_range
Definition: json.hpp:18491
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:20312
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:20274
binary_t & get_binary()
get a binary value
Definition: json.hpp:20193
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19322
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22473
basic_json(const JsonRef &ref)
Definition: json.hpp:19432
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:22450
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:19521
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:19294
reference back()
access the last element
Definition: json.hpp:20647
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:20205
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:22542
StringType string_t
a type for a string
Definition: json.hpp:18648
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:21364
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:20294
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:18549
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:20587
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:18640
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:18517
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:20087
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:18515
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19250
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21356
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:19142
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:18525
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:22788
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:20951
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:22743
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:18523
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:22575
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:18652
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21427
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:19561
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:20409
std::decay< ValueType >::type value(KeyType &&key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:20555
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:20668
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:20905
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:22559
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:22773
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:19597
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:21658
JSON_PRIVATE_UNLESS_TESTED const_reference bool static SAX bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
Definition: json.hpp:22321
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20228
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19283
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:19590
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:19632
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:22466
void swap(object_t &other)
exchanges the values
Definition: json.hpp:21749
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:19646
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20978
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:20462
const_reference front() const
access the first element
Definition: json.hpp:20640
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:19583
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:18664
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:18532
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19436
~basic_json() noexcept
destructor
Definition: json.hpp:19542
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:20937
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:22496
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19504
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:20969
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:22515
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:21555
json_value m_value
the value of the current element
Definition: json.hpp:22433
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:21794
void swap(array_t &other)
exchanges the values
Definition: json.hpp:21734
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19261
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.hpp:18631
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:20134
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:20332
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:21575
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20074
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:22875
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:23332
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19834
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:21606
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:18644
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:20111
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:20486
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:20738
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:19611
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:21705
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:22649
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:19667
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) const _reference operator[](const
access specified element via JSON Pointer
Definition: json.hpp:22853
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:19302
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:21548
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:22703
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:20350
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:22566
std::decay< ValueType >::type value(const char *key, ValueType &&default_value) const
Definition: json.hpp:20538
string_t value(KeyType &&key, const char *default_value) const
access specified object element with default value
Definition: json.hpp:20578
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:21779
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:18528
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:18534
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:22688
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:22507
string_t value(const char *key, const char *default_value) const
Definition: json.hpp:20543
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:20961
void swap(string_t &other)
exchanges the values
Definition: json.hpp:21764
const_reference back() const
access the last element
Definition: json.hpp:20656
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:19272
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:19660
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:19653
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:21509
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) ValueType value(const
access specified object element via JSON Pointer with default value
Definition: json.hpp:20608
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:22397
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:18512
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:22591
reference operator[](T *key)
Definition: json.hpp:20447
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:19618
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:21443
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:19625
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:18473
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:22459
detail::value_t value_t
Definition: json.hpp:18463
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:20854
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22489
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:20431
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:18672
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:19116
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:22758
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference operator[](const
Definition: json.hpp:22839
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:20396
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:18520
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:18668
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:18467
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:21396
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference at(const
Definition: json.hpp:22867
JSON_PRIVATE_UNLESS_TESTED const_reference rhs
Definition: json.hpp:21895
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:20985
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:22634
string_t value(const typename object_t::key_type &key, const char *default_value) const
access specified object element with default value
Definition: json.hpp:20527
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.hpp:19128
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:18660
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:20891
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:21419
std::decay< ValueType >::type value(const KeyType &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:20506
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:22382
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:19194
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:20251
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:21528
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:18530
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:19674
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:19604
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:21722
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:22534
JSON_PRIVATE_UNLESS_TESTED const_reference bool inverse
Definition: json.hpp:21895
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20033
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:21477
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22482
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:21388
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:20843
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:22375
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:19309
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:18541
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19845
an internal type for a backed binary type
Definition: json.hpp:5382
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5403
BinaryType container_type
Definition: json.hpp:5384
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5393
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5398
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5422
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5451
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5388
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5410
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5444
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5429
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5437
std::uint64_t subtype_type
Definition: json.hpp:5385
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5416
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:8652
binary_reader & operator=(const binary_reader &)=delete
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:8668
binary_reader & operator=(binary_reader &&)=default
binary_reader(const binary_reader &)=delete
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:8689
binary_reader(binary_reader &&)=default
serialization to CBOR and MessagePack values
Definition: json.hpp:14220
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.hpp:14919
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16004
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:14231
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:15982
void write_bson(const BasicJsonType &j)
Definition: json.hpp:14240
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:14269
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:15975
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:14593
general exception of the basic_json class
Definition: json.hpp:3931
const int id
the id of the exception
Definition: json.hpp:3940
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:3951
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:3957
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:3946
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:3934
Definition: json.hpp:5655
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
char char_type
Definition: json.hpp:5657
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5671
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:5715
~input_stream_adapter()
Definition: json.hpp:5696
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(const input_stream_adapter &)=delete
char char_type
Definition: json.hpp:5694
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::char_traits< char >::int_type get_character()
Definition: json.hpp:5725
input_stream_adapter(std::istream &i)
Definition: json.hpp:5706
exception indicating errors with iterators
Definition: json.hpp:4082
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4085
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12250
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:12716
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12846
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:12707
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:12443
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12280
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:12630
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:12857
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:12362
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:12289
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:12482
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:12769
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:12284
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:12387
pointer operator->() const
dereference the iterator
Definition: json.hpp:12526
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:12352
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:12377
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:12949
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:12824
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:12835
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:12924
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:12671
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:12760
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12278
reference value() const
return the value of an iterator
Definition: json.hpp:12940
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:12579
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12886
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:12751
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:12568
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12275
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:12619
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12778
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:12815
std::input_iterator_tag iterator_category
Definition: json.hpp:4700
iteration_proxy_value(iteration_proxy_value const &)=default
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:4765
iteration_proxy_value(IteratorType it, std::size_t array_index_=0) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_default_constructible< string_type >::value)
Definition: json.hpp:4717
iteration_proxy_value operator++(int) &
Definition: json.hpp:4750
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:4701
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:4807
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:4742
std::ptrdiff_t difference_type
Definition: json.hpp:4696
const string_type & key() const
return key of the iterator
Definition: json.hpp:4771
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:4759
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
proxy class for the items() function
Definition: json.hpp:4815
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4834
iteration_proxy(iteration_proxy &&) noexcept=default
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4840
iteration_proxy & operator=(iteration_proxy const &)=default
iteration_proxy(iteration_proxy const &)=default
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4824
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:5749
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5751
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:5755
Definition: json.hpp:13979
json_ref(json_ref &&) noexcept=default
value_type const & operator*() const
Definition: json.hpp:14018
BasicJsonType value_type
Definition: json.hpp:13981
json_ref(Args &&... args)
Definition: json.hpp:13998
json_ref(const value_type &value)
Definition: json.hpp:13987
value_type const * operator->() const
Definition: json.hpp:14023
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:13991
json_ref(value_type &&value)
Definition: json.hpp:13983
value_type moved_or_copied() const
Definition: json.hpp:14009
a template for a reverse iterator class
Definition: json.hpp:12991
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:13000
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:12997
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13043
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13031
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:12995
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13004
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13055
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13019
std::ptrdiff_t difference_type
Definition: json.hpp:12993
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13049
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13037
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13007
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13061
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13025
reference value() const
return the value of an iterator
Definition: json.hpp:13068
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13013
Definition: json.hpp:6751
bool end_array()
Definition: json.hpp:6814
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:6794
typename BasicJsonType::string_t string_t
Definition: json.hpp:6756
bool binary(binary_t &)
Definition: json.hpp:6789
bool boolean(bool)
Definition: json.hpp:6764
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6753
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6755
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6757
bool key(string_t &)
Definition: json.hpp:6799
bool end_object()
Definition: json.hpp:6804
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:6809
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:6819
bool number_integer(number_integer_t)
Definition: json.hpp:6769
bool string(string_t &)
Definition: json.hpp:6784
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:6774
bool null()
Definition: json.hpp:6759
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6754
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:6779
typename BasicJsonType::string_t string_t
Definition: json.hpp:6449
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
bool start_object(std::size_t len)
Definition: json.hpp:6511
bool key(string_t &val)
Definition: json.hpp:6529
constexpr bool is_errored() const
Definition: json.hpp:6644
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6447
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6446
bool null()
Definition: json.hpp:6469
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6451
bool start_array(std::size_t len)
Definition: json.hpp:6582
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6450
bool binary(binary_t &val)
Definition: json.hpp:6505
bool number_integer(number_integer_t val)
Definition: json.hpp:6481
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6448
bool end_array()
Definition: json.hpp:6599
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6452
bool boolean(bool val)
Definition: json.hpp:6475
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6487
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool string(string_t &val)
Definition: json.hpp:6499
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6493
bool end_object()
Definition: json.hpp:6546
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6632
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6454
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6261
bool start_array(std::size_t len)
Definition: json.hpp:6359
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6267
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6303
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6263
bool boolean(bool val)
Definition: json.hpp:6291
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6382
bool string(string_t &val)
Definition: json.hpp:6315
bool end_object()
Definition: json.hpp:6349
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6264
bool start_object(std::size_t len)
Definition: json.hpp:6327
bool null()
Definition: json.hpp:6285
bool binary(binary_t &val)
Definition: json.hpp:6321
constexpr bool is_errored() const
Definition: json.hpp:6394
bool key(string_t &val)
Definition: json.hpp:6339
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6265
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6309
bool end_array()
Definition: json.hpp:6371
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6274
typename BasicJsonType::string_t string_t
Definition: json.hpp:6266
bool number_integer(number_integer_t val)
Definition: json.hpp:6297
Definition: json.hpp:6858
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:6885
token_type
token types for the parser
Definition: json.hpp:6862
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
lexical analysis
Definition: json.hpp:6935
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8253
token_type scan()
Definition: json.hpp:8331
void skip_whitespace()
Definition: json.hpp:8323
lexer & operator=(lexer &&)=default
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8309
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:6946
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8263
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8235
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:6944
lexer & operator=(lexer &)=delete
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8241
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8247
std::string get_token_string() const
Definition: json.hpp:8271
lexer(lexer &&)=default
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8296
exception indicating other library errors
Definition: json.hpp:4134
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4137
exception indicating access out of the defined range
Definition: json.hpp:4117
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4120
Definition: json.hpp:14179
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:14186
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:14182
output_adapter(StringType &s)
Definition: json.hpp:14190
output adapter for output streams
Definition: json.hpp:14131
void write_character(CharType c) override
Definition: json.hpp:14137
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14133
output adapter for basic_string
Definition: json.hpp:14156
void write_character(CharType c) override
Definition: json.hpp:14162
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:14158
output adapter for byte vectors
Definition: json.hpp:14106
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14108
void write_character(CharType c) override
Definition: json.hpp:14112
exception indicating a parse error
Definition: json.hpp:4029
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.hpp:4041
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4049
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4066
syntax analysis
Definition: json.hpp:11603
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:11703
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:11613
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:11695
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:11635
Definition: json.hpp:12077
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12127
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12139
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12112
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12171
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12106
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12122
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12145
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12094
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12117
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12134
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12152
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12100
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12088
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12158
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12165
Definition: json.hpp:17183
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18115
const std::lconv * loc
the locale
Definition: json.hpp:18100
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:18097
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition: json.hpp:18104
std::uint8_t state
Definition: json.hpp:17525
std::size_t bytes
Definition: json.hpp:17526
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:18102
serializer & operator=(const serializer &)=delete
std::size_t undumped_chars
Definition: json.hpp:17530
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:17238
const char indent_char
the indentation character
Definition: json.hpp:18110
std::size_t bytes_after_last_accept
Definition: json.hpp:17529
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:18107
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.hpp:17523
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:17198
serializer(const serializer &)=delete
string_t indent_string
the indentation string
Definition: json.hpp:18112
Definition: json.hpp:6073
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6091
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6081
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6088
exception indicating executing a member function with a wrong type
Definition: json.hpp:4100
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4103
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5914
char char_type
Definition: json.hpp:5909
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:5911
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:13110
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:13194
void pop_back()
remove last reference token
Definition: json.hpp:13222
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:13201
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13208
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:13260
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13179
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13246
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13132
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13161
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:13186
friend class json_pointer
Definition: json.hpp:13116
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13142
friend bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:13950
const string_t & back() const
return last reference token
Definition: json.hpp:13234
friend bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:13957
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13171
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13136
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13253
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:4886
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2453
#define JSON_HEDLEY_CONST
Definition: json.hpp:1609
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:893
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2356
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1239
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2416
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:52
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1504
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1397
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2383
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:1838
#define JSON_CATCH(exception)
Definition: json.hpp:2382
#define JSON_ASSERT(x)
Definition: json.hpp:2409
#define JSON_THROW(exception)
Definition: json.hpp:2380
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:2684
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:50
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2462
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1505
#define JSON_TRY
Definition: json.hpp:2381
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2362
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:51
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:894
#define JSON_EXPLICIT
Definition: json.hpp:2674
#define JSON_HEDLEY_PURE
Definition: json.hpp:1578
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:21818
void init()
Definition: main.cpp:120
int map[20][10][20]
Definition: main.cpp:63
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:16858
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:17010
Target reinterpret_bits(const Source source)
Definition: json.hpp:16078
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:16219
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:16522
constexpr int kGamma
Definition: json.hpp:16342
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:16576
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:16958
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:16617
constexpr int kAlpha
Definition: json.hpp:16341
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:16358
detail namespace with internal helper functions
Definition: json.hpp:2167
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:2919
typename T::reference reference_t
Definition: json.hpp:3282
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:3845
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2753
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3367
typename T::key_compare detect_key_compare
Definition: json.hpp:3351
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3291
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:3842
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5157
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition: json.hpp:3463
value_t
the JSON type enumeration
Definition: json.hpp:2724
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4193
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3023
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:8521
typename T::pointer pointer_t
Definition: json.hpp:3279
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8494
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:3830
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:11594
typename std::conditional< is_key_type_comparable< BasicJsonType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, typename BasicJsonType::object_t::key_type >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, typename BasicJsonType::object_comparator_t >::value) &&!is_json_iterator_of< BasicJsonType, KeyType >::value &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition: json.hpp:3727
typename T::difference_type difference_type_t
Definition: json.hpp:3276
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:2216
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:4687
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4347
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:2961
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:8506
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8478
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:3833
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8498
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8482
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:17095
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5280
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3460
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:2229
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:2905
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:8624
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
parse_event_t
Definition: json.hpp:11577
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
error_handler_t
how to treat decoding errors
Definition: json.hpp:17175
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8502
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5989
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition: json.hpp:3739
typename T::key_type key_type_t
Definition: json.hpp:3270
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5488
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5506
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2834
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3007
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8486
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:2225
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:2222
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:8513
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition: json.hpp:4536
void concat_into(OutStringType &)
Definition: json.hpp:3823
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4207
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2814
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:2210
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:3848
typename make_void< Ts... >::type void_t
Definition: json.hpp:2172
OutStringType concat(Args &&... args)
Definition: json.hpp:3907
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3015
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14101
typename T::mapped_type mapped_type_t
Definition: json.hpp:3267
input_format_t
the supported input formats
Definition: json.hpp:5643
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:5274
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:3827
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4530
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3294
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:3730
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition: json.hpp:4430
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:3839
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6046
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3707
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8474
typename is_comparable< typename BasicJsonType::object_comparator_t, const key_type_t< typename BasicJsonType::object_t > &, KeyType >::type is_key_type_comparable
Definition: json.hpp:3704
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4850
typename T::iterator_category iterator_category_t
Definition: json.hpp:3285
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8490
std::size_t concat_length()
Definition: json.hpp:3792
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:3836
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:8516
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:4595
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:8509
T conditional_static_cast(U value)
Definition: json.hpp:3761
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3288
typename T::value_type value_type_t
Definition: json.hpp:3273
namespace for Niels Lohmann
Definition: json.hpp:2165
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:23364
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin)
bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.hpp:13957
bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.hpp:13950
Definition: json.hpp:4870
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:23414
void begin(GLenum shape)
Definition: tigl.cpp:133
void end()
Definition: tigl.cpp:143
default JSONSerializer template argument
Definition: json.hpp:5335
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:5339
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:5349
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:5359
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3361
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3363
typename BasicJsonType::object_t object_t
Definition: json.hpp:3360
Definition: json.hpp:3375
Definition: json.hpp:3374
Definition: json.hpp:2197
Default type
Definition: json.hpp:2199
std::false_type value_t
Definition: json.hpp:2198
Definition: json.hpp:16206
diyfp plus
Definition: json.hpp:16209
diyfp w
Definition: json.hpp:16207
diyfp minus
Definition: json.hpp:16208
std::uint64_t f
Definition: json.hpp:16346
int k
Definition: json.hpp:16348
int e
Definition: json.hpp:16347
Definition: json.hpp:16088
static constexpr int kPrecision
Definition: json.hpp:16089
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:16177
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:16194
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16112
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16094
int e
Definition: json.hpp:16092
std::uint64_t f
Definition: json.hpp:16091
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16100
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5069
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5098
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5082
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5057
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5047
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:4986
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:4995
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:4940
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5008
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5034
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5021
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5127
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5117
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5138
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:4962
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:4973
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:4953
Definition: json.hpp:4625
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:4627
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3313
Definition: json.hpp:3298
Definition: json.hpp:3354
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3328
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3343
Definition: json.hpp:3338
Definition: json.hpp:4163
Definition: json.hpp:2947
T value_type
Definition: json.hpp:2948
static constexpr std::size_t size() noexcept
Definition: json.hpp:2949
an iterator value
Definition: json.hpp:12192
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12198
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12196
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:12194
Definition: json.hpp:3234
Definition: json.hpp:3691
static constexpr auto value
Definition: json.hpp:3535
Definition: json.hpp:3661
Definition: json.hpp:3470
static constexpr auto value
Definition: json.hpp:3549
ConstructibleStringType laundered_type
Definition: json.hpp:3546
Definition: json.hpp:3407
Definition: json.hpp:2213
Definition: json.hpp:3306
static constexpr bool value
Definition: json.hpp:3307
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:5966
Definition: json.hpp:3423
Definition: json.hpp:3670
Definition: json.hpp:3257
Definition: json.hpp:3749
char x[2]
Definition: json.hpp:3750
Definition: json.hpp:3745
@ value
Definition: json.hpp:3756
char one
Definition: json.hpp:3746
static one test(decltype(&C::capacity))
Definition: json.hpp:3442
static constexpr bool value
Definition: json.hpp:3456
Definition: json.hpp:8525
static constexpr bool value
Definition: json.hpp:8538
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5977
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5954
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:5957
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:5955
IteratorType iterator_type
Definition: json.hpp:5953
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3107
Definition: json.hpp:3095
Definition: json.hpp:3076
Definition: json.hpp:2169
void type
Definition: json.hpp:2170
Definition: json.hpp:3381
Definition: json.hpp:2183
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition: json.hpp:14087
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
output_adapter_protocol(const output_adapter_protocol &)=default
struct to capture the start position of the current token
Definition: json.hpp:2869
std::size_t lines_read
the number of lines read
Definition: json.hpp:2875
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:2873
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:2871
Definition: json.hpp:3031
Definition: json.hpp:3030
Definition: json.hpp:3036
static constexpr T value
Definition: json.hpp:3037
Definition: json.hpp:5300
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:5302
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:2988
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5846
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5788
SAX interface.
Definition: json.hpp:6130
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string value was read
virtual bool null()=0
a null value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6131
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6135
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6132
virtual bool binary(binary_t &val)=0
a binary value was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6133
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition: json.hpp:6134
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
a minimal map-like container that preserves insertion order
Definition: json.hpp:18147
T & at(const Key &key)
Definition: json.hpp:18194
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:18150
T mapped_type
Definition: json.hpp:18149
const T & at(const Key &key) const
Definition: json.hpp:18207
iterator find(const Key &key)
Definition: json.hpp:18304
iterator erase(iterator pos)
Definition: json.hpp:18239
void insert(InputIt first, InputIt last)
Definition: json.hpp:18351
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:18328
const_iterator find(const Key &key) const
Definition: json.hpp:18316
Key key_type
Definition: json.hpp:18148
size_type erase(const Key &key)
Definition: json.hpp:18220
T & operator[](const Key &key)
Definition: json.hpp:18184
iterator erase(iterator first, iterator last)
Definition: json.hpp:18244
typename Container::const_iterator const_iterator
Definition: json.hpp:18152
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:18348
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:18166
std::equal_to< Key > key_compare
Definition: json.hpp:18158
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:18164
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:18333
typename Container::size_type size_type
Definition: json.hpp:18153
typename Container::value_type value_type
Definition: json.hpp:18154
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:18168
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:18163
size_type count(const Key &key) const
Definition: json.hpp:18292
typename Container::iterator iterator
Definition: json.hpp:18151
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:18171
const T & operator[](const Key &key) const
Definition: json.hpp:18189
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:23383
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:23397